@theia/core 1.66.0-next.44 → 1.66.0-next.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/authentication-service.d.ts +14 -10
- package/lib/browser/authentication-service.d.ts.map +1 -1
- package/lib/browser/authentication-service.js +23 -11
- package/lib/browser/authentication-service.js.map +1 -1
- package/lib/browser/catalog.json +17 -9
- package/lib/browser/credentials-service.d.ts +2 -0
- package/lib/browser/credentials-service.d.ts.map +1 -1
- package/lib/browser/credentials-service.js +6 -0
- package/lib/browser/credentials-service.js.map +1 -1
- package/lib/browser-only/frontend-only-application-module.d.ts.map +1 -1
- package/lib/browser-only/frontend-only-application-module.js +2 -1
- package/lib/browser-only/frontend-only-application-module.js.map +1 -1
- package/lib/common/content-replacer-v2-impl.d.ts +70 -0
- package/lib/common/content-replacer-v2-impl.d.ts.map +1 -0
- package/lib/common/content-replacer-v2-impl.js +407 -0
- package/lib/common/content-replacer-v2-impl.js.map +1 -0
- package/lib/common/content-replacer-v2-impl.spec.d.ts +2 -0
- package/lib/common/content-replacer-v2-impl.spec.d.ts.map +1 -0
- package/lib/common/content-replacer-v2-impl.spec.js +319 -0
- package/lib/common/content-replacer-v2-impl.spec.js.map +1 -0
- package/lib/common/content-replacer.d.ts +13 -1
- package/lib/common/content-replacer.d.ts.map +1 -1
- package/lib/common/content-replacer.js +3 -3
- package/lib/common/content-replacer.js.map +1 -1
- package/lib/common/content-replacer.spec.js +2 -2
- package/lib/common/content-replacer.spec.js.map +1 -1
- package/lib/common/key-store.d.ts +1 -0
- package/lib/common/key-store.d.ts.map +1 -1
- package/lib/node/key-store-server.d.ts +1 -0
- package/lib/node/key-store-server.d.ts.map +1 -1
- package/lib/node/key-store-server.js +4 -0
- package/lib/node/key-store-server.js.map +1 -1
- package/lib/node/key-store-server.spec.d.ts +2 -0
- package/lib/node/key-store-server.spec.d.ts.map +1 -0
- package/lib/node/key-store-server.spec.js +226 -0
- package/lib/node/key-store-server.spec.js.map +1 -0
- package/package.json +4 -4
- package/src/browser/authentication-service.ts +57 -18
- package/src/browser/credentials-service.ts +9 -0
- package/src/browser-only/frontend-only-application-module.ts +2 -1
- package/src/common/content-replacer-v2-impl.spec.ts +344 -0
- package/src/common/content-replacer-v2-impl.ts +471 -0
- package/src/common/content-replacer.spec.ts +4 -4
- package/src/common/content-replacer.ts +11 -1
- package/src/common/key-store.ts +1 -0
- package/src/node/key-store-server.spec.ts +262 -0
- package/src/node/key-store-server.ts +5 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 STMicroelectronics and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { expect } from 'chai';
|
|
18
|
+
import { KeyStoreServiceImpl, InMemoryCredentialsProvider } from './key-store-server';
|
|
19
|
+
|
|
20
|
+
describe('KeyStoreServiceImpl', () => {
|
|
21
|
+
let keyStoreService: KeyStoreServiceImpl;
|
|
22
|
+
let inMemoryProvider: InMemoryCredentialsProvider;
|
|
23
|
+
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
keyStoreService = new KeyStoreServiceImpl();
|
|
26
|
+
inMemoryProvider = new InMemoryCredentialsProvider();
|
|
27
|
+
// Force the service to use the in-memory provider for testing
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
29
|
+
(keyStoreService as any).keytarImplementation = inMemoryProvider;
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe('keys', () => {
|
|
33
|
+
it('should return an empty array when no credentials exist for the service', async () => {
|
|
34
|
+
const result = await keyStoreService.keys('test-service');
|
|
35
|
+
expect(result).to.be.an('array');
|
|
36
|
+
expect(result).to.be.empty;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should return a single account key when one credential exists', async () => {
|
|
40
|
+
await keyStoreService.setPassword('test-service', 'account1', 'password1');
|
|
41
|
+
const result = await keyStoreService.keys('test-service');
|
|
42
|
+
expect(result).to.deep.equal(['account1']);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should return multiple account keys when multiple credentials exist', async () => {
|
|
46
|
+
await keyStoreService.setPassword('test-service', 'account1', 'password1');
|
|
47
|
+
await keyStoreService.setPassword('test-service', 'account2', 'password2');
|
|
48
|
+
await keyStoreService.setPassword('test-service', 'account3', 'password3');
|
|
49
|
+
const result = await keyStoreService.keys('test-service');
|
|
50
|
+
expect(result).to.have.lengthOf(3);
|
|
51
|
+
expect(result).to.include.members(['account1', 'account2', 'account3']);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should only return keys for the specified service', async () => {
|
|
55
|
+
await keyStoreService.setPassword('service1', 'account1', 'password1');
|
|
56
|
+
await keyStoreService.setPassword('service2', 'account2', 'password2');
|
|
57
|
+
await keyStoreService.setPassword('service1', 'account3', 'password3');
|
|
58
|
+
|
|
59
|
+
const result = await keyStoreService.keys('service1');
|
|
60
|
+
expect(result).to.have.lengthOf(2);
|
|
61
|
+
expect(result).to.include.members(['account1', 'account3']);
|
|
62
|
+
expect(result).to.not.include('account2');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should return updated keys after a credential is deleted', async () => {
|
|
66
|
+
await keyStoreService.setPassword('test-service', 'account1', 'password1');
|
|
67
|
+
await keyStoreService.setPassword('test-service', 'account2', 'password2');
|
|
68
|
+
await keyStoreService.deletePassword('test-service', 'account1');
|
|
69
|
+
|
|
70
|
+
const result = await keyStoreService.keys('test-service');
|
|
71
|
+
expect(result).to.deep.equal(['account2']);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should return updated keys after a credential password is updated', async () => {
|
|
75
|
+
await keyStoreService.setPassword('test-service', 'account1', 'password1');
|
|
76
|
+
await keyStoreService.setPassword('test-service', 'account1', 'password2');
|
|
77
|
+
|
|
78
|
+
const result = await keyStoreService.keys('test-service');
|
|
79
|
+
expect(result).to.deep.equal(['account1']);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('should handle services with special characters in the name', async () => {
|
|
83
|
+
const specialService = 'test-service@#$%^&*()';
|
|
84
|
+
await keyStoreService.setPassword(specialService, 'account1', 'password1');
|
|
85
|
+
|
|
86
|
+
const result = await keyStoreService.keys(specialService);
|
|
87
|
+
expect(result).to.deep.equal(['account1']);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('should handle accounts with special characters in the name', async () => {
|
|
91
|
+
await keyStoreService.setPassword('test-service', 'user@example.com', 'password1');
|
|
92
|
+
await keyStoreService.setPassword('test-service', 'user-name_123', 'password2');
|
|
93
|
+
|
|
94
|
+
const result = await keyStoreService.keys('test-service');
|
|
95
|
+
expect(result).to.have.lengthOf(2);
|
|
96
|
+
expect(result).to.include.members(['user@example.com', 'user-name_123']);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe('setPassword', () => {
|
|
101
|
+
it('should set a password for an account', async () => {
|
|
102
|
+
await keyStoreService.setPassword('test-service', 'account1', 'password1');
|
|
103
|
+
const password = await keyStoreService.getPassword('test-service', 'account1');
|
|
104
|
+
expect(password).to.equal('password1');
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('should update an existing password', async () => {
|
|
108
|
+
await keyStoreService.setPassword('test-service', 'account1', 'password1');
|
|
109
|
+
await keyStoreService.setPassword('test-service', 'account1', 'password2');
|
|
110
|
+
const password = await keyStoreService.getPassword('test-service', 'account1');
|
|
111
|
+
expect(password).to.equal('password2');
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe('getPassword', () => {
|
|
116
|
+
it('should return undefined when password does not exist', async () => {
|
|
117
|
+
const password = await keyStoreService.getPassword('test-service', 'nonexistent');
|
|
118
|
+
expect(password).to.be.undefined;
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('should retrieve a stored password', async () => {
|
|
122
|
+
await keyStoreService.setPassword('test-service', 'account1', 'password1');
|
|
123
|
+
const password = await keyStoreService.getPassword('test-service', 'account1');
|
|
124
|
+
expect(password).to.equal('password1');
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
describe('deletePassword', () => {
|
|
129
|
+
it('should return false when deleting a non-existent password', async () => {
|
|
130
|
+
const result = await keyStoreService.deletePassword('test-service', 'nonexistent');
|
|
131
|
+
expect(result).to.be.false;
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('should return true when deleting an existing password', async () => {
|
|
135
|
+
await keyStoreService.setPassword('test-service', 'account1', 'password1');
|
|
136
|
+
const result = await keyStoreService.deletePassword('test-service', 'account1');
|
|
137
|
+
expect(result).to.be.true;
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should remove the password after deletion', async () => {
|
|
141
|
+
await keyStoreService.setPassword('test-service', 'account1', 'password1');
|
|
142
|
+
await keyStoreService.deletePassword('test-service', 'account1');
|
|
143
|
+
const password = await keyStoreService.getPassword('test-service', 'account1');
|
|
144
|
+
expect(password).to.be.undefined;
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
describe('findPassword', () => {
|
|
149
|
+
it('should return undefined when service has no credentials', async () => {
|
|
150
|
+
const result = await keyStoreService.findPassword('nonexistent-service');
|
|
151
|
+
expect(result).to.be.undefined;
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('should return the service credentials as JSON string', async () => {
|
|
155
|
+
await keyStoreService.setPassword('test-service', 'account1', 'password1');
|
|
156
|
+
const result = await keyStoreService.findPassword('test-service');
|
|
157
|
+
expect(result).to.be.a('string');
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
describe('findCredentials', () => {
|
|
162
|
+
it('should return an empty array when no credentials exist', async () => {
|
|
163
|
+
const result = await keyStoreService.findCredentials('test-service');
|
|
164
|
+
expect(result).to.be.an('array');
|
|
165
|
+
expect(result).to.be.empty;
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('should return all credentials for a service', async () => {
|
|
169
|
+
await keyStoreService.setPassword('test-service', 'account1', 'password1');
|
|
170
|
+
await keyStoreService.setPassword('test-service', 'account2', 'password2');
|
|
171
|
+
const result = await keyStoreService.findCredentials('test-service');
|
|
172
|
+
expect(result).to.have.lengthOf(2);
|
|
173
|
+
expect(result).to.deep.include({ account: 'account1', password: 'password1' });
|
|
174
|
+
expect(result).to.deep.include({ account: 'account2', password: 'password2' });
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
describe('InMemoryCredentialsProvider', () => {
|
|
180
|
+
let provider: InMemoryCredentialsProvider;
|
|
181
|
+
|
|
182
|
+
beforeEach(() => {
|
|
183
|
+
provider = new InMemoryCredentialsProvider();
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
describe('setPassword and getPassword', () => {
|
|
187
|
+
it('should store and retrieve a password', async () => {
|
|
188
|
+
await provider.setPassword('service1', 'account1', 'password1');
|
|
189
|
+
const result = await provider.getPassword('service1', 'account1');
|
|
190
|
+
expect(result).to.equal('password1');
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('should return null for non-existent password', async () => {
|
|
194
|
+
const result = await provider.getPassword('service1', 'account1');
|
|
195
|
+
expect(result).to.be.null;
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
describe('deletePassword', () => {
|
|
200
|
+
it('should return false when deleting non-existent password', async () => {
|
|
201
|
+
const result = await provider.deletePassword('service1', 'account1');
|
|
202
|
+
expect(result).to.be.false;
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it('should delete an existing password and return true', async () => {
|
|
206
|
+
await provider.setPassword('service1', 'account1', 'password1');
|
|
207
|
+
const result = await provider.deletePassword('service1', 'account1');
|
|
208
|
+
expect(result).to.be.true;
|
|
209
|
+
const password = await provider.getPassword('service1', 'account1');
|
|
210
|
+
expect(password).to.be.null;
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('should remove service entry when all accounts are deleted', async () => {
|
|
214
|
+
await provider.setPassword('service1', 'account1', 'password1');
|
|
215
|
+
await provider.deletePassword('service1', 'account1');
|
|
216
|
+
const credentials = await provider.findCredentials('service1');
|
|
217
|
+
expect(credentials).to.be.empty;
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
describe('findPassword', () => {
|
|
222
|
+
it('should return null for non-existent service', async () => {
|
|
223
|
+
const result = await provider.findPassword('service1');
|
|
224
|
+
expect(result).to.be.null;
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it('should return JSON string of service credentials', async () => {
|
|
228
|
+
await provider.setPassword('service1', 'account1', 'password1');
|
|
229
|
+
const result = await provider.findPassword('service1');
|
|
230
|
+
expect(result).to.be.a('string');
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
describe('findCredentials', () => {
|
|
235
|
+
it('should return empty array for non-existent service', async () => {
|
|
236
|
+
const result = await provider.findCredentials('service1');
|
|
237
|
+
expect(result).to.be.an('array');
|
|
238
|
+
expect(result).to.be.empty;
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it('should return all credentials for a service', async () => {
|
|
242
|
+
await provider.setPassword('service1', 'account1', 'password1');
|
|
243
|
+
await provider.setPassword('service1', 'account2', 'password2');
|
|
244
|
+
const result = await provider.findCredentials('service1');
|
|
245
|
+
expect(result).to.have.lengthOf(2);
|
|
246
|
+
expect(result).to.deep.include({ account: 'account1', password: 'password1' });
|
|
247
|
+
expect(result).to.deep.include({ account: 'account2', password: 'password2' });
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
describe('clear', () => {
|
|
252
|
+
it('should remove all stored credentials', async () => {
|
|
253
|
+
await provider.setPassword('service1', 'account1', 'password1');
|
|
254
|
+
await provider.setPassword('service2', 'account2', 'password2');
|
|
255
|
+
await provider.clear();
|
|
256
|
+
const credentials1 = await provider.findCredentials('service1');
|
|
257
|
+
const credentials2 = await provider.findCredentials('service2');
|
|
258
|
+
expect(credentials1).to.be.empty;
|
|
259
|
+
expect(credentials2).to.be.empty;
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
});
|
|
@@ -112,6 +112,11 @@ export class KeyStoreServiceImpl implements KeyStoreService {
|
|
|
112
112
|
}
|
|
113
113
|
return this.keytarImplementation;
|
|
114
114
|
}
|
|
115
|
+
|
|
116
|
+
async keys(service: string): Promise<string[]> {
|
|
117
|
+
const keytar = await this.getKeytar();
|
|
118
|
+
return (await keytar.findCredentials(service)).map(c => c.account);
|
|
119
|
+
}
|
|
115
120
|
}
|
|
116
121
|
|
|
117
122
|
export class InMemoryCredentialsProvider {
|