1 | 'use strict';
|
2 |
|
3 |
|
4 |
|
5 | const fs = require('fs');
|
6 |
|
7 |
|
8 |
|
9 | const pify = require('pify');
|
10 | const mkdirp = pify(require('mkdirp'));
|
11 |
|
12 |
|
13 |
|
14 | const jsonUtils = require('./utils/json');
|
15 | const scope = require('./scope');
|
16 | const urlUtils = require('./utils/url');
|
17 | const values = require('./values');
|
18 |
|
19 |
|
20 |
|
21 | const fsp = pify(fs);
|
22 |
|
23 | function login (options) {
|
24 | options = options || {};
|
25 |
|
26 | let projectScope;
|
27 | return scope.read()
|
28 | .then((s) => {
|
29 | projectScope = s;
|
30 | })
|
31 | .catch(() => {
|
32 | throw new Error('must set project scope first');
|
33 | })
|
34 | .then(() => mkdirp(values.USER_CONFIG_DIR))
|
35 | .then(() => {
|
36 | return jsonUtils.updateJson(values.USER_CONFIG_FILE, (cfg) => {
|
37 | cfg.bmp = cfg.bmp || {};
|
38 | const origin = urlUtils.getOrigin(projectScope);
|
39 | cfg.bmp[origin] = {
|
40 | credential: options.credential
|
41 | };
|
42 | return cfg;
|
43 | }, {
|
44 | mode: 0o600
|
45 | });
|
46 | });
|
47 | }
|
48 |
|
49 | function logout () {
|
50 | const EXITEARLYHACK = 'EXITEARLYHACK';
|
51 |
|
52 | let projectScope;
|
53 | return scope.read()
|
54 | .then((s) => {
|
55 | projectScope = s;
|
56 | })
|
57 | .catch(() => {
|
58 | throw new Error('must set project scope first');
|
59 | })
|
60 | .then(() => fsp.access(values.USER_CONFIG_FILE, fs.F_OK))
|
61 | .catch(() => {
|
62 | return Promise.reject(new Error('EXITEARLYHACK'));
|
63 | })
|
64 | .then(() => fsp.access(values.USER_CONFIG_FILE, fs.R_OK | fs.W_OK))
|
65 | .then(() => {
|
66 | return jsonUtils.updateJson(values.USER_CONFIG_FILE, (cfg) => {
|
67 | cfg.bmp = cfg.bmp || {};
|
68 | const origin = urlUtils.getOrigin(projectScope);
|
69 | if (cfg.bmp[origin]) {
|
70 | delete cfg.bmp[origin].credential;
|
71 | }
|
72 | return cfg;
|
73 | }, {
|
74 | mode: 0o600
|
75 | });
|
76 | })
|
77 | .catch((err) => {
|
78 | if (err.message !== EXITEARLYHACK) {
|
79 | return Promise.reject(err);
|
80 | }
|
81 | });
|
82 | }
|
83 |
|
84 | function readAll () {
|
85 | return jsonUtils.loadJsonObject(values.USER_CONFIG_FILE)
|
86 | .catch((err) => {
|
87 | if (err.code === 'ENOENT') {
|
88 |
|
89 | return {};
|
90 | }
|
91 |
|
92 | throw err;
|
93 | })
|
94 | .then((obj) => {
|
95 | const bmp = obj.bmp || {};
|
96 | return Object.keys(bmp)
|
97 | .filter((origin) => !!bmp[origin].credential)
|
98 | .map((origin) => {
|
99 | const credential = bmp[origin].credential;
|
100 | return { origin, credential };
|
101 | });
|
102 | });
|
103 | }
|
104 |
|
105 | function read () {
|
106 | let origin;
|
107 | return scope.read()
|
108 | .then((projectScope) => {
|
109 | origin = urlUtils.getOrigin(urlUtils.toHTTPS(projectScope) || '');
|
110 | })
|
111 | .then(readAll)
|
112 | .then((auths) => {
|
113 | const matches = auths.filter((a) => a.origin === origin);
|
114 | if (matches.length) {
|
115 | return matches[0];
|
116 | }
|
117 | throw new Error(`not yet logged in for scope origin: ${origin}`);
|
118 | });
|
119 | }
|
120 |
|
121 | module.exports = {
|
122 | login,
|
123 | logout,
|
124 | read,
|
125 | readAll
|
126 | };
|