Skip to content

Commit d1ab00f

Browse files
authored
Merge branch 'master' into master
2 parents 7533cf4 + 5025c85 commit d1ab00f

File tree

8 files changed

+1993
-33
lines changed

8 files changed

+1993
-33
lines changed

.github/workflows/test.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
on:
2+
push:
3+
branches:
4+
- master
5+
pull_request:
6+
branches:
7+
- master
8+
9+
jobs:
10+
build:
11+
runs-on: macos-latest
12+
strategy:
13+
matrix:
14+
node: [ 14, 16, 18 ]
15+
steps:
16+
- uses: actions/checkout@v3
17+
- uses: actions/setup-node@v3
18+
with:
19+
node-version: ${{ matrix.node }}
20+
- run: npm install
21+
- run: npm test

.travis.yml

Lines changed: 0 additions & 25 deletions
This file was deleted.

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# Basic Keychain Access on Mac computers running Node.js
2-
[![Build Status](https://travis-ci.org/drudge/node-keychain.svg)](https://travis-ci.org/drudge/node-keychain)
1+
# Basic Keychain Access on Mac computers running Node.js
2+
[![Build Status](https://img.shields.io/github/actions/workflow/status/drudge/node-keychain/test.yaml?branch=master)](https://github.com/drudge/node-keychain/actions/workflows/test.yaml)
33

44
This module adds methods for basic Keychain access in Node.js by way of the `security` command-line tool.
55

@@ -45,6 +45,9 @@ The available
4545
keychain.setPassword(options[, callback]);
4646
keychain.getPassword(options, callback);
4747
keychain.deletePassword(options[, callback]);
48+
keychain.createKeychain(options[, callback]);
49+
keychain.deleteKeychain(options[, callback]);
50+
keychain.setDefaultKeychain(options[, callback]);
4851
```
4952

5053
### Options
@@ -57,6 +60,7 @@ Available params you can pass to the options object:
5760
| `service` | Specify service name (required) |
5861
| `password` | Specify password to be added (required for `setPassword`) |
5962
| `type` | The type of password to get or save. Supported values are `generic` and `internet`. See [docs](https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/security.1.html). Default: `generic` |
63+
| `keychainName` | Specify the name of the keychain (required for 'createKeychain' and 'deleteKeychain') |
6064

6165
## Contributors
6266

keychain.js

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,127 @@ KeychainAccess.prototype.deletePassword = function(opts, fn) {
244244
});
245245
};
246246

247+
/**
248+
* Create a new keychain to be used in the system.
249+
*
250+
* @param {Object} opts Object containing 'keychainName' and `password`
251+
* @param {Function} fn Callback
252+
* @api public
253+
*/
254+
KeychainAccess.prototype.createKeychain = function(opts, fn) {
255+
opts = opts || {};
256+
fn = fn || noop;
257+
258+
if (!opts.keychainName) {
259+
err = new KeychainAccess.errors.NoKeychainNameProvidedError();
260+
fn(err, null);
261+
return;
262+
}
263+
264+
if (!opts.password) {
265+
err = new KeychainAccess.errors.NoPasswordProvidedError();
266+
fn(err, null);
267+
return;
268+
}
269+
270+
var security = spawn(this.executablePath, [ 'create-keychain', '-p', opts.password, opts.keychainName]);
271+
272+
security.on('error', function(err) {
273+
err = new KeychainAccess.errors.ServiceFailureError(null, err.message);
274+
fn(err, null);
275+
return;
276+
});
277+
278+
security.on('close', function(code, signal) {
279+
if (code !== 0) {
280+
var msg = 'Security returned a non-successful error code: ' + code;
281+
err = new KeychainAccess.errors.ServiceFailureError(msg);
282+
err.exitCode = code;
283+
fn(err);
284+
return;
285+
} else {
286+
fn(null, opts.keychainName);
287+
}
288+
});
289+
};
290+
291+
/**
292+
* Delete a keychain from the system.
293+
*
294+
* @param {Object} opts Object containing 'keychainName'
295+
* @param {Function} fn Callback
296+
* @api public
297+
*/
298+
KeychainAccess.prototype.deleteKeychain = function(opts, fn) {
299+
opts = opts || {};
300+
fn = fn || noop;
301+
302+
if (!opts.keychainName) {
303+
err = new KeychainAccess.errors.NoKeychainNameProvidedError();
304+
fn(err, null);
305+
return;
306+
}
307+
308+
var security = spawn(this.executablePath, [ 'delete-keychain', opts.keychainName]);
309+
310+
security.on('error', function(err) {
311+
err = new KeychainAccess.errors.ServiceFailureError(null, err.message);
312+
fn(err, null);
313+
return;
314+
});
315+
316+
security.on('close', function(code, signal) {
317+
if (code !== 0) {
318+
var msg = 'Security returned a non-successful error code: ' + code;
319+
err = new KeychainAccess.errors.ServiceFailureError(msg);
320+
err.exitCode = code;
321+
fn(err);
322+
return;
323+
} else {
324+
fn(null, opts.keychainName);
325+
}
326+
});
327+
328+
};
329+
330+
/**
331+
* Set the default keychain for the system.
332+
*
333+
* @param {Object} opts Object containing 'keychainName'
334+
* @param {Function} fn Callback
335+
* @api public
336+
*/
337+
KeychainAccess.prototype.setDefaultKeychain = function(opts, fn) {
338+
opts = opts || {};
339+
fn = fn || noop;
340+
341+
if (!opts.keychainName) {
342+
err = new KeychainAccess.errors.NoKeychainNameProvidedError();
343+
fn(err, null);
344+
return;
345+
}
346+
347+
var security = spawn(this.executablePath, [ 'default-keychain', '-s', opts.keychainName]);
348+
349+
security.on('error', function(err) {
350+
err = new KeychainAccess.errors.ServiceFailureError(null, err.message);
351+
fn(err, null);
352+
return;
353+
});
354+
355+
security.on('close', function(code, signal) {
356+
if (code !== 0) {
357+
var msg = 'Security returned a non-successful error code: ' + code;
358+
err = new KeychainAccess.errors.ServiceFailureError(msg);
359+
err.exitCode = code;
360+
fn(err);
361+
return;
362+
} else {
363+
fn(null, opts.keychainName);
364+
}
365+
});
366+
};
367+
247368
function errorClass(code, defaultMsg) {
248369
var errorType = code + 'Error';
249370
var ErrorClass = function (msg, append) {
@@ -265,6 +386,7 @@ errorClass('NoServiceProvided', 'A service is required');
265386
errorClass('NoPasswordProvided', 'A password is required');
266387
errorClass('ServiceFailure', 'Keychain failed to start child process: ');
267388
errorClass('PasswordNotFound', 'Could not find password');
389+
errorClass('NoKeychainNameProvided', 'A keychain name is required');
268390

269391

270392
/**

0 commit comments

Comments
 (0)