UNPKG

appcenter-cli

Version:

Command line tool for Visual Studio App Center

124 lines (123 loc) 5.12 kB
"use strict"; // Token store implementation over OSX keychain Object.defineProperty(exports, "__esModule", { value: true }); exports.createOsxTokenStore = exports.OsxTokenStore = void 0; // // Access to the OSX keychain - list, add, get password, remove // const _ = require("lodash"); const rx = require("rxjs"); const childProcess = require("child_process"); const from = require("from2"); const split = require("split2"); const through = require("through2"); const osx_keychain_parser_1 = require("./osx-keychain-parser"); const debug = require("debug")("appcenter-cli:util:token-store:osx:osx-token-store"); const util_1 = require("util"); const securityPath = "/usr/bin/security"; const serviceName = "appcenter-cli"; const oldServiceName = "mobile-center-cli"; class OsxTokenStore { list() { return rx.Observable.create((observer) => { const securityProcess = childProcess.spawn(securityPath, ["dump-keychain"]); const securityStream = securityProcess.stdout .pipe(split()) .pipe(through(function (line, enc, done) { done(null, line.toString().replace(/\\134/g, "\\")); })) .pipe(new osx_keychain_parser_1.OsxSecurityParsingStream()); securityStream.on("data", (data) => { debug(`listing, got data ${util_1.inspect(data)}`); if (data.svce !== serviceName) { debug(`service does not match, skipping`); return; } const key = data.acct; // Have to get specific token to get tokens, but we have ids const accessToken = { id: data.gena, token: null, }; debug(`Outputting ${util_1.inspect({ key, accessToken })}`); observer.next({ key, accessToken }); }); securityStream.on("end", (err) => { debug(`output from security program complete`); if (err) { observer.error(err); } else { observer.complete(); } }); }); } get(key, useOldName = false) { const args = ["find-generic-password", "-a", key, "-s", useOldName ? oldServiceName : serviceName, "-g"]; return new Promise((resolve, reject) => { resolve = _.once(resolve); reject = _.once(reject); childProcess.execFile(securityPath, args, (err, stdout, stderr) => { if (err) { return reject(err); } const match = /^password: (?:0x[0-9A-F]+. )?"(.*)"$/m.exec(stderr); if (match) { const accessToken = match[1].replace(/\\134/g, "\\"); debug(`stdout for security program = "${stdout}"`); debug(`parsing stdout`); // Parse the rest of the information from stdout to get user & token ID const parsed = from([stdout]).pipe(osx_keychain_parser_1.createOsxSecurityParsingStream()); parsed.on("data", (data) => { debug(`got data on key lookup: ${util_1.inspect(data)}`); resolve({ key: data.acct, accessToken: { id: data.gena, token: accessToken, }, }); }); parsed.on("error", (err) => { debug(`parsed string failed`); reject(err); }); } else { reject(new Error("Password in incorrect format")); } }); }); } set(key, value) { const args = ["add-generic-password", "-a", key, "-D", "appcenter cli password", "-s", serviceName, "-w", value.token, "-U"]; if (value.id) { args.push("-G", value.id); } return new Promise((resolve, reject) => { childProcess.execFile(securityPath, args, function (err, stdout, stderr) { if (err) { return reject(new Error("Could not add password to keychain: " + stderr)); } return resolve(); }); }); } remove(key) { const args = ["delete-generic-password", "-a", key, "-s", serviceName]; return new Promise((resolve, reject) => { childProcess.execFile(securityPath, args, function (err, stdout, stderr) { if (err) { return reject(new Error("Could not remove account from keychain, " + stderr)); } return resolve(); }); }); } } exports.OsxTokenStore = OsxTokenStore; function createOsxTokenStore() { return new OsxTokenStore(); } exports.createOsxTokenStore = createOsxTokenStore;