UNPKG

2.97 kBJavaScriptView Raw
1'use strict';
2
3// Node.js built-ins
4
5const fs = require('fs');
6
7// foreign modules
8
9const pify = require('pify');
10const mkdirp = pify(require('mkdirp'));
11
12// local modules
13
14const jsonUtils = require('./utils/json');
15const scope = require('./scope');
16const urlUtils = require('./utils/url');
17const values = require('./values');
18
19// this module
20
21const fsp = pify(fs);
22
23function 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
49function 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
84function readAll () {
85 return jsonUtils.loadJsonObject(values.USER_CONFIG_FILE)
86 .catch((err) => {
87 if (err.code === 'ENOENT') {
88 // missing file = not authenticated, which we handle further down
89 return {};
90 }
91 // throw every other error, e.g. corrupt file, bad permissions, etc
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
105function 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
121module.exports = {
122 login,
123 logout,
124 read,
125 readAll
126};