react-native-keychain/RNKeychainManager/RNKeychainManager.m

94 lines
3.5 KiB
Mathematica
Raw Normal View History

2015-05-20 16:23:04 +00:00
//
// RNKeychainManager.m
// RNKeychainManager
//
// Created by Joel Arvidsson on 2015-05-20.
// Copyright (c) 2015 Joel Arvidsson. All rights reserved.
//
#import <Security/Security.h>
#import "RNKeychainManager.h"
#import "RCTConvert.h"
#import "RCTBridge.h"
2015-05-28 17:08:18 +00:00
#import "RCTUtils.h"
2015-05-20 16:23:04 +00:00
@implementation RNKeychainManager
@synthesize bridge = _bridge;
RCT_EXPORT_MODULE();
2015-05-28 17:08:18 +00:00
NSDictionary * makeError(NSError *error)
{
return RCTMakeAndLogError(error.localizedDescription, nil, [error dictionaryWithValuesForKeys:@[@"domain", @"code"]]);
}
2015-05-20 16:23:04 +00:00
2015-05-20 18:39:52 +00:00
RCT_EXPORT_METHOD(setInternetCredentialsForServer:(NSString*)server withUsername:(NSString*)username withPassword:(NSString*)password callback:(RCTResponseSenderBlock)callback){
// Create dictionary of search parameters
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)(kSecClassInternetPassword), kSecClass, server, kSecAttrServer, kCFBooleanTrue, kSecReturnAttributes, nil];
// Remove any old values from the keychain
OSStatus osStatus = SecItemDelete((__bridge CFDictionaryRef) dict);
// Create dictionary of parameters to add
NSData* passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
dict = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)(kSecClassInternetPassword), kSecClass, server, kSecAttrServer, passwordData, kSecValueData, username, kSecAttrAccount, nil];
// Try to save to keychain
osStatus = SecItemAdd((__bridge CFDictionaryRef) dict, NULL);
2015-05-28 17:08:18 +00:00
if (osStatus != noErr) {
2015-05-20 18:39:52 +00:00
NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:osStatus userInfo:nil];
2015-05-28 17:08:18 +00:00
return callback(@[makeError(error)]);
2015-05-20 18:39:52 +00:00
}
callback(@[[NSNull null]]);
}
RCT_EXPORT_METHOD(getInternetCredentialsForServer:(NSString*)server callback:(RCTResponseSenderBlock)callback){
// Create dictionary of search parameters
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)(kSecClassInternetPassword), kSecClass, server, kSecAttrServer, kCFBooleanTrue, kSecReturnAttributes, kCFBooleanTrue, kSecReturnData, nil];
// Look up server in the keychain
NSDictionary* found = nil;
CFTypeRef foundTypeRef = NULL;
OSStatus osStatus = SecItemCopyMatching((__bridge CFDictionaryRef) dict, (CFTypeRef*)&foundTypeRef);
2015-05-20 18:39:52 +00:00
2015-05-28 17:08:18 +00:00
if (osStatus != noErr) {
2015-05-20 18:39:52 +00:00
NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:osStatus userInfo:nil];
2015-05-28 17:08:18 +00:00
return callback(@[makeError(error)]);
2015-05-20 18:39:52 +00:00
}
found = (__bridge NSDictionary*)(foundTypeRef);
if (!found) {
return callback(@[[NSNull null]]);
}
// Found
NSString* username = (NSString*) [found objectForKey:(__bridge id)(kSecAttrAccount)];
NSString* password = [[NSString alloc] initWithData:[found objectForKey:(__bridge id)(kSecValueData)] encoding:NSUTF8StringEncoding];
2015-05-20 18:39:52 +00:00
callback(@[[NSNull null], username, password]);
}
RCT_EXPORT_METHOD(resetInternetCredentialsForServer:(NSString*)server callback:(RCTResponseSenderBlock)callback){
// Create dictionary of search parameters
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)(kSecClassInternetPassword), kSecClass, server, kSecAttrServer, kCFBooleanTrue, kSecReturnAttributes, kCFBooleanTrue, kSecReturnData, nil];
// Remove any old values from the keychain
OSStatus osStatus = SecItemDelete((__bridge CFDictionaryRef) dict);
2015-05-28 17:08:18 +00:00
if (osStatus != noErr) {
2015-05-20 18:39:52 +00:00
NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:osStatus userInfo:nil];
2015-05-28 17:08:18 +00:00
return callback(@[makeError(error)]);
2015-05-20 18:39:52 +00:00
}
callback(@[[NSNull null]]);
}
2015-05-20 16:23:04 +00:00
@end