1 | "use strict";
|
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3 | if (k2 === undefined) k2 = k;
|
4 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
5 | }) : (function(o, m, k, k2) {
|
6 | if (k2 === undefined) k2 = k;
|
7 | o[k2] = m[k];
|
8 | }));
|
9 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
10 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
11 | }) : function(o, v) {
|
12 | o["default"] = v;
|
13 | });
|
14 | var __importStar = (this && this.__importStar) || function (mod) {
|
15 | if (mod && mod.__esModule) return mod;
|
16 | var result = {};
|
17 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
18 | __setModuleDefault(result, mod);
|
19 | return result;
|
20 | };
|
21 | Object.defineProperty(exports, "__esModule", { value: true });
|
22 | exports.listPublishers = exports.deletePublisher = exports.logoutPublisher = exports.loginPublisher = exports.getPublisher = exports.verifyPat = exports.KeytarStore = exports.FileStore = void 0;
|
23 | const fs = __importStar(require("fs"));
|
24 | const path = __importStar(require("path"));
|
25 | const os_1 = require("os");
|
26 | const util_1 = require("./util");
|
27 | const validation_1 = require("./validation");
|
28 | const package_1 = require("./package");
|
29 | class FileStore {
|
30 | constructor(path, publishers) {
|
31 | this.path = path;
|
32 | this.publishers = publishers;
|
33 | }
|
34 | static async open(path = FileStore.DefaultPath) {
|
35 | try {
|
36 | const rawStore = await fs.promises.readFile(path, 'utf8');
|
37 | return new FileStore(path, JSON.parse(rawStore).publishers);
|
38 | }
|
39 | catch (err) {
|
40 | if (err.code === 'ENOENT') {
|
41 | return new FileStore(path, []);
|
42 | }
|
43 | else if (/SyntaxError/.test(err)) {
|
44 | throw new Error(`Error parsing file store: ${path}`);
|
45 | }
|
46 | throw err;
|
47 | }
|
48 | }
|
49 | get size() {
|
50 | return this.publishers.length;
|
51 | }
|
52 | async save() {
|
53 | await fs.promises.writeFile(this.path, JSON.stringify({ publishers: this.publishers }), { mode: '0600' });
|
54 | }
|
55 | async deleteStore() {
|
56 | try {
|
57 | await fs.promises.unlink(this.path);
|
58 | }
|
59 | catch {
|
60 |
|
61 | }
|
62 | }
|
63 | get(name) {
|
64 | return this.publishers.filter(p => p.name === name)[0];
|
65 | }
|
66 | async add(publisher) {
|
67 | this.publishers = [...this.publishers.filter(p => p.name !== publisher.name), publisher];
|
68 | await this.save();
|
69 | }
|
70 | async delete(name) {
|
71 | this.publishers = this.publishers.filter(p => p.name !== name);
|
72 | await this.save();
|
73 | }
|
74 | [Symbol.iterator]() {
|
75 | return this.publishers[Symbol.iterator]();
|
76 | }
|
77 | }
|
78 | exports.FileStore = FileStore;
|
79 | FileStore.DefaultPath = path.join((0, os_1.homedir)(), '.vsce');
|
80 | class KeytarStore {
|
81 | constructor(keytar, serviceName, publishers) {
|
82 | this.keytar = keytar;
|
83 | this.serviceName = serviceName;
|
84 | this.publishers = publishers;
|
85 | }
|
86 | static async open(serviceName = 'vscode-vsce') {
|
87 | const keytar = await Promise.resolve().then(() => __importStar(require('keytar')));
|
88 | const creds = await keytar.findCredentials(serviceName);
|
89 | return new KeytarStore(keytar, serviceName, creds.map(({ account, password }) => ({ name: account, pat: password })));
|
90 | }
|
91 | get size() {
|
92 | return this.publishers.length;
|
93 | }
|
94 | get(name) {
|
95 | return this.publishers.filter(p => p.name === name)[0];
|
96 | }
|
97 | async add(publisher) {
|
98 | this.publishers = [...this.publishers.filter(p => p.name !== publisher.name), publisher];
|
99 | await this.keytar.setPassword(this.serviceName, publisher.name, publisher.pat);
|
100 | }
|
101 | async delete(name) {
|
102 | this.publishers = this.publishers.filter(p => p.name !== name);
|
103 | await this.keytar.deletePassword(this.serviceName, name);
|
104 | }
|
105 | [Symbol.iterator]() {
|
106 | return this.publishers[Symbol.iterator]();
|
107 | }
|
108 | }
|
109 | exports.KeytarStore = KeytarStore;
|
110 | async function verifyPat(pat, publisherName) {
|
111 | if (!pat) {
|
112 | throw new Error('The Personal Access Token is mandatory.');
|
113 | }
|
114 | if (!publisherName) {
|
115 | try {
|
116 | publisherName = (await (0, package_1.readManifest)()).publisher;
|
117 | }
|
118 | catch (error) {
|
119 | throw new Error(`Can not read the publisher's name. Either supply it as an argument or run vsce from the extension folder. Additional information:\n\n${error}`);
|
120 | }
|
121 | }
|
122 | try {
|
123 |
|
124 |
|
125 |
|
126 | const api = await (0, util_1.getSecurityRolesAPI)(pat);
|
127 | await api.getRoleAssignments('gallery.publisher', publisherName);
|
128 | }
|
129 | catch (error) {
|
130 | throw new Error('The Personal Access Token verification has failed. Additional information:\n\n' + error);
|
131 | }
|
132 | console.log(`The Personal Access Token verification succeeded for the publisher '${publisherName}'.`);
|
133 | }
|
134 | exports.verifyPat = verifyPat;
|
135 | async function requestPAT(publisherName) {
|
136 | console.log('https://marketplace.visualstudio.com/manage/publishers/');
|
137 | const pat = await (0, util_1.read)(`Personal Access Token for publisher '${publisherName}':`, { silent: true, replace: '*' });
|
138 | await verifyPat(pat, publisherName);
|
139 | return pat;
|
140 | }
|
141 | async function openDefaultStore() {
|
142 | if (/^file$/i.test(process.env['VSCE_STORE'] ?? '')) {
|
143 | return await FileStore.open();
|
144 | }
|
145 | let keytarStore;
|
146 | try {
|
147 | keytarStore = await KeytarStore.open();
|
148 | }
|
149 | catch (err) {
|
150 | const store = await FileStore.open();
|
151 | util_1.log.warn(`Failed to open credential store. Falling back to storing secrets clear-text in: ${store.path}`);
|
152 | return store;
|
153 | }
|
154 | const fileStore = await FileStore.open();
|
155 |
|
156 | if (fileStore.size) {
|
157 | for (const publisher of fileStore) {
|
158 | await keytarStore.add(publisher);
|
159 | }
|
160 | await fileStore.deleteStore();
|
161 | util_1.log.info(`Migrated ${fileStore.size} publishers to system credential manager. Deleted local store '${fileStore.path}'.`);
|
162 | }
|
163 | return keytarStore;
|
164 | }
|
165 | async function getPublisher(publisherName) {
|
166 | (0, validation_1.validatePublisher)(publisherName);
|
167 | const store = await openDefaultStore();
|
168 | let publisher = store.get(publisherName);
|
169 | if (publisher) {
|
170 | return publisher;
|
171 | }
|
172 | const pat = await requestPAT(publisherName);
|
173 | publisher = { name: publisherName, pat };
|
174 | await store.add(publisher);
|
175 | return publisher;
|
176 | }
|
177 | exports.getPublisher = getPublisher;
|
178 | async function loginPublisher(publisherName) {
|
179 | (0, validation_1.validatePublisher)(publisherName);
|
180 | const store = await openDefaultStore();
|
181 | let publisher = store.get(publisherName);
|
182 | if (publisher) {
|
183 | console.log(`Publisher '${publisherName}' is already known`);
|
184 | const answer = await (0, util_1.read)('Do you want to overwrite its PAT? [y/N] ');
|
185 | if (!/^y$/i.test(answer)) {
|
186 | throw new Error('Aborted');
|
187 | }
|
188 | }
|
189 | const pat = await requestPAT(publisherName);
|
190 | publisher = { name: publisherName, pat };
|
191 | await store.add(publisher);
|
192 | return publisher;
|
193 | }
|
194 | exports.loginPublisher = loginPublisher;
|
195 | async function logoutPublisher(publisherName) {
|
196 | (0, validation_1.validatePublisher)(publisherName);
|
197 | const store = await openDefaultStore();
|
198 | const publisher = store.get(publisherName);
|
199 | if (!publisher) {
|
200 | throw new Error(`Unknown publisher '${publisherName}'`);
|
201 | }
|
202 | await store.delete(publisherName);
|
203 | }
|
204 | exports.logoutPublisher = logoutPublisher;
|
205 | async function deletePublisher(publisherName) {
|
206 | const publisher = await getPublisher(publisherName);
|
207 | const answer = await (0, util_1.read)(`This will FOREVER delete '${publisherName}'! Are you sure? [y/N] `);
|
208 | if (!/^y$/i.test(answer)) {
|
209 | throw new Error('Aborted');
|
210 | }
|
211 | const api = await (0, util_1.getGalleryAPI)(publisher.pat);
|
212 | await api.deletePublisher(publisherName);
|
213 | const store = await openDefaultStore();
|
214 | await store.delete(publisherName);
|
215 | util_1.log.done(`Deleted publisher '${publisherName}'.`);
|
216 | }
|
217 | exports.deletePublisher = deletePublisher;
|
218 | async function listPublishers() {
|
219 | const store = await openDefaultStore();
|
220 | for (const publisher of store) {
|
221 | console.log(publisher.name);
|
222 | }
|
223 | }
|
224 | exports.listPublishers = listPublishers;
|
225 |
|
\ | No newline at end of file |