latchkey 3.7.0 → 3.9.0
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/dist/scripts/recordBrowserSession.js +4 -3
- package/dist/scripts/recordBrowserSession.js.map +1 -1
- package/dist/src/apiCredentials/base.d.ts +7 -1
- package/dist/src/apiCredentials/base.d.ts.map +1 -1
- package/dist/src/apiCredentials/base.js.map +1 -1
- package/dist/src/apiCredentials/store.d.ts +5 -0
- package/dist/src/apiCredentials/store.d.ts.map +1 -1
- package/dist/src/apiCredentials/store.js +7 -0
- package/dist/src/apiCredentials/store.js.map +1 -1
- package/dist/src/atomicWrite.d.ts +4 -1
- package/dist/src/atomicWrite.d.ts.map +1 -1
- package/dist/src/atomicWrite.js +34 -3
- package/dist/src/atomicWrite.js.map +1 -1
- package/dist/src/cli.js +0 -3
- package/dist/src/cli.js.map +1 -1
- package/dist/src/cliCommands.d.ts +8 -0
- package/dist/src/cliCommands.d.ts.map +1 -1
- package/dist/src/cliCommands.js +88 -13
- package/dist/src/cliCommands.js.map +1 -1
- package/dist/src/curl.d.ts +36 -0
- package/dist/src/curl.d.ts.map +1 -1
- package/dist/src/curl.js +42 -0
- package/dist/src/curl.js.map +1 -1
- package/dist/src/curlInjection.d.ts +5 -4
- package/dist/src/curlInjection.d.ts.map +1 -1
- package/dist/src/curlInjection.js +8 -7
- package/dist/src/curlInjection.js.map +1 -1
- package/dist/src/gateway/gatewayEndpoint.d.ts.map +1 -1
- package/dist/src/gateway/gatewayEndpoint.js +6 -3
- package/dist/src/gateway/gatewayEndpoint.js.map +1 -1
- package/dist/src/gateway/server.d.ts.map +1 -1
- package/dist/src/gateway/server.js +14 -3
- package/dist/src/gateway/server.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/migrations.d.ts +6 -0
- package/dist/src/migrations.d.ts.map +1 -1
- package/dist/src/migrations.js +21 -8
- package/dist/src/migrations.js.map +1 -1
- package/dist/src/playwrightUtils.d.ts +57 -0
- package/dist/src/playwrightUtils.d.ts.map +1 -1
- package/dist/src/playwrightUtils.js +247 -8
- package/dist/src/playwrightUtils.js.map +1 -1
- package/dist/src/serviceRegistry.d.ts +14 -1
- package/dist/src/serviceRegistry.d.ts.map +1 -1
- package/dist/src/serviceRegistry.js +22 -2
- package/dist/src/serviceRegistry.js.map +1 -1
- package/dist/src/services/aws.d.ts +11 -2
- package/dist/src/services/aws.d.ts.map +1 -1
- package/dist/src/services/aws.js +72 -5
- package/dist/src/services/aws.js.map +1 -1
- package/dist/src/services/core/base.d.ts +55 -16
- package/dist/src/services/core/base.d.ts.map +1 -1
- package/dist/src/services/core/base.js +119 -31
- package/dist/src/services/core/base.js.map +1 -1
- package/dist/src/services/github.d.ts +2 -1
- package/dist/src/services/github.d.ts.map +1 -1
- package/dist/src/services/github.js +13 -0
- package/dist/src/services/github.js.map +1 -1
- package/dist/src/services/huggingface.d.ts +2 -1
- package/dist/src/services/huggingface.d.ts.map +1 -1
- package/dist/src/services/huggingface.js +13 -0
- package/dist/src/services/huggingface.js.map +1 -1
- package/dist/src/services/linear.d.ts +2 -1
- package/dist/src/services/linear.d.ts.map +1 -1
- package/dist/src/services/linear.js +14 -0
- package/dist/src/services/linear.js.map +1 -1
- package/dist/src/services/ngrok.d.ts +2 -1
- package/dist/src/services/ngrok.d.ts.map +1 -1
- package/dist/src/services/ngrok.js +12 -0
- package/dist/src/services/ngrok.js.map +1 -1
- package/dist/src/services/openrouter.d.ts +2 -1
- package/dist/src/services/openrouter.d.ts.map +1 -1
- package/dist/src/services/openrouter.js +12 -0
- package/dist/src/services/openrouter.js.map +1 -1
- package/dist/src/services/tailscale.d.ts +2 -1
- package/dist/src/services/tailscale.d.ts.map +1 -1
- package/dist/src/services/tailscale.js +18 -0
- package/dist/src/services/tailscale.js.map +1 -1
- package/dist/src/services/todoist.d.ts +2 -1
- package/dist/src/services/todoist.d.ts.map +1 -1
- package/dist/src/services/todoist.js +6 -0
- package/dist/src/services/todoist.js.map +1 -1
- package/dist/src/services/zoom.d.ts +2 -1
- package/dist/src/services/zoom.d.ts.map +1 -1
- package/dist/src/services/zoom.js +55 -55
- package/dist/src/services/zoom.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/tests/apiCredentialStore.test.js +8 -0
- package/dist/tests/apiCredentialStore.test.js.map +1 -1
- package/dist/tests/apiCredentials.test.js +84 -1
- package/dist/tests/apiCredentials.test.js.map +1 -1
- package/dist/tests/atomicWrite.test.js +42 -1
- package/dist/tests/atomicWrite.test.js.map +1 -1
- package/dist/tests/builtinServiceRegistry.d.ts +10 -0
- package/dist/tests/builtinServiceRegistry.d.ts.map +1 -0
- package/dist/tests/builtinServiceRegistry.js +10 -0
- package/dist/tests/builtinServiceRegistry.js.map +1 -0
- package/dist/tests/cli.test.js +155 -7
- package/dist/tests/cli.test.js.map +1 -1
- package/dist/tests/devShim.test.d.ts +2 -0
- package/dist/tests/devShim.test.d.ts.map +1 -0
- package/dist/tests/devShim.test.js +240 -0
- package/dist/tests/devShim.test.js.map +1 -0
- package/dist/tests/gateway.test.js +87 -2
- package/dist/tests/gateway.test.js.map +1 -1
- package/dist/tests/gatewayExtensions.test.js +2 -0
- package/dist/tests/gatewayExtensions.test.js.map +1 -1
- package/dist/tests/github.test.js +2 -2
- package/dist/tests/github.test.js.map +1 -1
- package/dist/tests/huggingface.test.js +2 -2
- package/dist/tests/huggingface.test.js.map +1 -1
- package/dist/tests/latchkeyEndpoint.test.js +9 -5
- package/dist/tests/latchkeyEndpoint.test.js.map +1 -1
- package/dist/tests/lint.test.js +1 -1
- package/dist/tests/manualCompletion.test.d.ts +10 -0
- package/dist/tests/manualCompletion.test.d.ts.map +1 -0
- package/dist/tests/manualCompletion.test.js +221 -0
- package/dist/tests/manualCompletion.test.js.map +1 -0
- package/dist/tests/manualCredentialForms.test.d.ts +8 -0
- package/dist/tests/manualCredentialForms.test.d.ts.map +1 -0
- package/dist/tests/manualCredentialForms.test.js +64 -0
- package/dist/tests/manualCredentialForms.test.js.map +1 -0
- package/dist/tests/serviceRegistry.test.js +104 -20
- package/dist/tests/serviceRegistry.test.js.map +1 -1
- package/dist/tests/servicesAgainstRecordings.test.js +2 -2
- package/dist/tests/servicesAgainstRecordings.test.js.map +1 -1
- package/dist/tests/tailscale.test.js +2 -2
- package/dist/tests/tailscale.test.js.map +1 -1
- package/package.json +4 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A registry over the services latchkey ships with.
|
|
3
|
+
*
|
|
4
|
+
* The CLI and the gateway each build their own registry with
|
|
5
|
+
* `createServiceRegistry`, since theirs also carry whatever config.json holds.
|
|
6
|
+
* Tests that only care about the built-in services share this one.
|
|
7
|
+
*/
|
|
8
|
+
import { ServiceRegistry } from '../src/serviceRegistry.js';
|
|
9
|
+
export declare const BUILTIN_SERVICE_REGISTRY: ServiceRegistry;
|
|
10
|
+
//# sourceMappingURL=builtinServiceRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtinServiceRegistry.d.ts","sourceRoot":"","sources":["../../tests/builtinServiceRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAoB,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE9E,eAAO,MAAM,wBAAwB,iBAAwC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A registry over the services latchkey ships with.
|
|
3
|
+
*
|
|
4
|
+
* The CLI and the gateway each build their own registry with
|
|
5
|
+
* `createServiceRegistry`, since theirs also carry whatever config.json holds.
|
|
6
|
+
* Tests that only care about the built-in services share this one.
|
|
7
|
+
*/
|
|
8
|
+
import { BUILTIN_SERVICES, ServiceRegistry } from '../src/serviceRegistry.js';
|
|
9
|
+
export const BUILTIN_SERVICE_REGISTRY = new ServiceRegistry(BUILTIN_SERVICES);
|
|
10
|
+
//# sourceMappingURL=builtinServiceRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtinServiceRegistry.js","sourceRoot":"","sources":["../../tests/builtinServiceRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE9E,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,eAAe,CAAC,gBAAgB,CAAC,CAAC"}
|
package/dist/tests/cli.test.js
CHANGED
|
@@ -5,12 +5,13 @@ import { tmpdir } from 'node:os';
|
|
|
5
5
|
import { execSync } from 'node:child_process';
|
|
6
6
|
import { Command } from 'commander';
|
|
7
7
|
import { registerCommands } from '../src/cliCommands.js';
|
|
8
|
-
import { CurlParseError, extractUrlFromCurlArguments } from '../src/curl.js';
|
|
8
|
+
import { CurlParseError, extractUrlFromCurlArguments, resolveCurlRequestBodySource, } from '../src/curl.js';
|
|
9
9
|
import { hasGraphicalEnvironment } from '../src/playwrightUtils.js';
|
|
10
10
|
import { EncryptedStorage } from '../src/encryptedStorage.js';
|
|
11
11
|
import { Config } from '../src/config.js';
|
|
12
12
|
import { ServiceRegistry } from '../src/serviceRegistry.js';
|
|
13
13
|
import { ApiCredentialStatus } from '../src/apiCredentials/base.js';
|
|
14
|
+
import { LATEST_VERSION } from '../src/migrations.js';
|
|
14
15
|
import { Service } from '../src/services/core/base.js';
|
|
15
16
|
import { createMockService, MockService } from './mockService.js';
|
|
16
17
|
import { RegisteredService } from '../src/services/core/registered.js';
|
|
@@ -183,6 +184,26 @@ describe('extractUrlFromCurlArguments', () => {
|
|
|
183
184
|
expect(extractUrlFromCurlArguments(arguments_)).toBe('https://example.com/api?query=from%3Ame');
|
|
184
185
|
});
|
|
185
186
|
});
|
|
187
|
+
describe('resolveCurlRequestBodySource', () => {
|
|
188
|
+
it('should report an inline body when no file reference is present', () => {
|
|
189
|
+
expect(resolveCurlRequestBodySource(['-d', '{"a":1}', 'https://example.com'], '{"a":1}')).toEqual({ kind: 'inline', text: '{"a":1}' });
|
|
190
|
+
});
|
|
191
|
+
it('should report an inline body for --data-raw, which treats @ literally', () => {
|
|
192
|
+
expect(resolveCurlRequestBodySource(['--data-raw', '@literal', 'https://example.com'], '@literal')).toEqual({ kind: 'inline', text: '@literal' });
|
|
193
|
+
});
|
|
194
|
+
it('should report a file reference', () => {
|
|
195
|
+
expect(resolveCurlRequestBodySource(['--data-binary', '@/tmp/payload.json', 'https://example.com'], '@/tmp/payload.json')).toEqual({ kind: 'file', path: '/tmp/payload.json' });
|
|
196
|
+
});
|
|
197
|
+
it('should report stdin for @-', () => {
|
|
198
|
+
expect(resolveCurlRequestBodySource(['--data-binary', '@-', 'https://example.com'], '@-')).toEqual({ kind: 'stdin' });
|
|
199
|
+
});
|
|
200
|
+
it('should report an unreconstructable body for combined data arguments', () => {
|
|
201
|
+
expect(resolveCurlRequestBodySource(['-d', '@/tmp/payload.json', '-d', 'extra=1', 'https://example.com'], '@/tmp/payload.json&extra=1')).toEqual({ kind: 'unreconstructable' });
|
|
202
|
+
});
|
|
203
|
+
it('should report an unreconstructable body for url-encoded file data', () => {
|
|
204
|
+
expect(resolveCurlRequestBodySource(['--data-urlencode', '@/tmp/payload.json', 'https://example.com'], '@/tmp/payload.json')).toEqual({ kind: 'unreconstructable' });
|
|
205
|
+
});
|
|
206
|
+
});
|
|
186
207
|
describe('hasGraphicalEnvironment', () => {
|
|
187
208
|
const originalPlatform = process.platform;
|
|
188
209
|
afterEach(() => {
|
|
@@ -345,6 +366,7 @@ describe('CLI commands with dependency injection', () => {
|
|
|
345
366
|
const mockRegistry = new ServiceRegistry([mockSlackService]);
|
|
346
367
|
return {
|
|
347
368
|
registry: mockRegistry,
|
|
369
|
+
builtinServices: [mockSlackService],
|
|
348
370
|
config: createMockConfig(),
|
|
349
371
|
runCurl: (args) => {
|
|
350
372
|
capturedArgs.push(...args);
|
|
@@ -973,11 +995,27 @@ describe('CLI commands with dependency injection', () => {
|
|
|
973
995
|
function withStdinKey(key, overrides = {}) {
|
|
974
996
|
return createMockDependencies({ readStdin: () => Promise.resolve(key), ...overrides });
|
|
975
997
|
}
|
|
976
|
-
// The
|
|
998
|
+
// The filenames used by the mock config.
|
|
977
999
|
const STORE_FILENAME = 'credentials.json';
|
|
978
|
-
|
|
979
|
-
|
|
1000
|
+
const BROWSER_STATE_FILENAME = 'browser_state.json';
|
|
1001
|
+
function writeStore(contents, preparations = {}) {
|
|
1002
|
+
writeSecureFile(join(tempDir, STORE_FILENAME), JSON.stringify({ ...nestAccounts(contents), preparations }));
|
|
1003
|
+
}
|
|
1004
|
+
function readPreparationsWithKey(path, key) {
|
|
1005
|
+
const raw = JSON.parse(new EncryptedStorage(key).readFile(path) ?? '{}');
|
|
1006
|
+
return raw.preparations ?? {};
|
|
980
1007
|
}
|
|
1008
|
+
// A destination that already holds a store must be in the current data
|
|
1009
|
+
// format, which real Latchkey directories record in this file.
|
|
1010
|
+
function stampDataFormatVersion(directory) {
|
|
1011
|
+
mkdirSync(directory, { recursive: true });
|
|
1012
|
+
writeFileSync(join(directory, 'data-format-version'), String(LATEST_VERSION));
|
|
1013
|
+
}
|
|
1014
|
+
const GITLAB_PREPARATION = {
|
|
1015
|
+
objectType: 'oauth',
|
|
1016
|
+
clientId: 'gitlab-client-id',
|
|
1017
|
+
clientSecret: 'gitlab-client-secret',
|
|
1018
|
+
};
|
|
981
1019
|
it('re-encrypts all stored credentials with the new key', async () => {
|
|
982
1020
|
writeStore({
|
|
983
1021
|
slack: { objectType: 'slack', token: 'tok', dCookie: 'cookie' },
|
|
@@ -1025,7 +1063,7 @@ describe('CLI commands with dependency injection', () => {
|
|
|
1025
1063
|
const reEncrypted = readWithKey(join(destinationDirectory, STORE_FILENAME), NEW_ENCRYPTION_KEY);
|
|
1026
1064
|
expect(Object.keys(reEncrypted)).toEqual(['slack']);
|
|
1027
1065
|
});
|
|
1028
|
-
it('errors when a requested service has
|
|
1066
|
+
it('errors when a requested service has neither credentials nor a preparation', async () => {
|
|
1029
1067
|
writeStore({ slack: { objectType: 'slack', token: 'tok', dCookie: 'cookie' } });
|
|
1030
1068
|
const destinationDirectory = join(tempDir, 'export');
|
|
1031
1069
|
const deps = withStdinKey(NEW_ENCRYPTION_KEY);
|
|
@@ -1033,6 +1071,60 @@ describe('CLI commands with dependency injection', () => {
|
|
|
1033
1071
|
expect(exitCode).toBe(1);
|
|
1034
1072
|
expect(existsSync(join(destinationDirectory, STORE_FILENAME))).toBe(false);
|
|
1035
1073
|
});
|
|
1074
|
+
it('carries the preparations of the re-encrypted services', async () => {
|
|
1075
|
+
writeStore({ gitlab: { objectType: 'authorizationBearer', token: 'gitlab-token' } }, { gitlab: GITLAB_PREPARATION });
|
|
1076
|
+
const destinationDirectory = join(tempDir, 'export');
|
|
1077
|
+
const deps = withStdinKey(NEW_ENCRYPTION_KEY);
|
|
1078
|
+
await runCommand(['auth', 're-encrypt', destinationDirectory], deps);
|
|
1079
|
+
expect(exitCode).toBeNull();
|
|
1080
|
+
const destination = join(destinationDirectory, STORE_FILENAME);
|
|
1081
|
+
expect(readPreparationsWithKey(destination, NEW_ENCRYPTION_KEY)).toEqual({
|
|
1082
|
+
gitlab: GITLAB_PREPARATION,
|
|
1083
|
+
});
|
|
1084
|
+
});
|
|
1085
|
+
it('includes services that only have a preparation', async () => {
|
|
1086
|
+
writeStore({ slack: { objectType: 'slack', token: 'tok', dCookie: 'cookie' } }, { gitlab: GITLAB_PREPARATION });
|
|
1087
|
+
const destinationDirectory = join(tempDir, 'export');
|
|
1088
|
+
const deps = withStdinKey(NEW_ENCRYPTION_KEY);
|
|
1089
|
+
await runCommand(['auth', 're-encrypt', destinationDirectory], deps);
|
|
1090
|
+
expect(exitCode).toBeNull();
|
|
1091
|
+
const destination = join(destinationDirectory, STORE_FILENAME);
|
|
1092
|
+
expect(Object.keys(readWithKey(destination, NEW_ENCRYPTION_KEY))).toEqual(['slack']);
|
|
1093
|
+
expect(readPreparationsWithKey(destination, NEW_ENCRYPTION_KEY)).toEqual({
|
|
1094
|
+
gitlab: GITLAB_PREPARATION,
|
|
1095
|
+
});
|
|
1096
|
+
expect(logs.join('\n')).toContain('2 service(s)');
|
|
1097
|
+
});
|
|
1098
|
+
it('selects a service that only has a preparation with --services', async () => {
|
|
1099
|
+
writeStore({ slack: { objectType: 'slack', token: 'tok', dCookie: 'cookie' } }, { gitlab: GITLAB_PREPARATION });
|
|
1100
|
+
const destinationDirectory = join(tempDir, 'export');
|
|
1101
|
+
const deps = withStdinKey(NEW_ENCRYPTION_KEY);
|
|
1102
|
+
await runCommand(['auth', 're-encrypt', destinationDirectory, '--services', 'gitlab'], deps);
|
|
1103
|
+
expect(exitCode).toBeNull();
|
|
1104
|
+
const destination = join(destinationDirectory, STORE_FILENAME);
|
|
1105
|
+
expect(readWithKey(destination, NEW_ENCRYPTION_KEY)).toEqual({});
|
|
1106
|
+
expect(readPreparationsWithKey(destination, NEW_ENCRYPTION_KEY)).toEqual({
|
|
1107
|
+
gitlab: GITLAB_PREPARATION,
|
|
1108
|
+
});
|
|
1109
|
+
});
|
|
1110
|
+
it('replaces an existing preparation in the destination', async () => {
|
|
1111
|
+
writeStore({}, { gitlab: GITLAB_PREPARATION });
|
|
1112
|
+
const destinationDirectory = join(tempDir, 'export');
|
|
1113
|
+
const destination = join(destinationDirectory, STORE_FILENAME);
|
|
1114
|
+
stampDataFormatVersion(destinationDirectory);
|
|
1115
|
+
new EncryptedStorage(NEW_ENCRYPTION_KEY).writeFile(destination, JSON.stringify({
|
|
1116
|
+
credentials: {},
|
|
1117
|
+
preparations: {
|
|
1118
|
+
gitlab: { objectType: 'oauth', clientId: 'old-id', clientSecret: 'old-secret' },
|
|
1119
|
+
},
|
|
1120
|
+
}));
|
|
1121
|
+
const deps = withStdinKey(NEW_ENCRYPTION_KEY);
|
|
1122
|
+
await runCommand(['auth', 're-encrypt', destinationDirectory], deps);
|
|
1123
|
+
expect(exitCode).toBeNull();
|
|
1124
|
+
expect(readPreparationsWithKey(destination, NEW_ENCRYPTION_KEY)).toEqual({
|
|
1125
|
+
gitlab: GITLAB_PREPARATION,
|
|
1126
|
+
});
|
|
1127
|
+
});
|
|
1036
1128
|
it('errors for an invalid encryption key read from stdin', async () => {
|
|
1037
1129
|
writeStore({});
|
|
1038
1130
|
const destinationDirectory = join(tempDir, 'export');
|
|
@@ -1049,10 +1141,36 @@ describe('CLI commands with dependency injection', () => {
|
|
|
1049
1141
|
expect(exitCode).toBeNull();
|
|
1050
1142
|
expect(Object.keys(readWithKey(join(destinationDirectory, STORE_FILENAME), NEW_ENCRYPTION_KEY))).toEqual(['slack']);
|
|
1051
1143
|
});
|
|
1052
|
-
it('
|
|
1144
|
+
it('adds the services into an existing credential store, overwriting by service', async () => {
|
|
1145
|
+
writeStore({
|
|
1146
|
+
slack: { objectType: 'slack', token: 'new-tok', dCookie: 'new-cookie' },
|
|
1147
|
+
});
|
|
1148
|
+
const destinationDirectory = join(tempDir, 'export');
|
|
1149
|
+
const destination = join(destinationDirectory, STORE_FILENAME);
|
|
1150
|
+
stampDataFormatVersion(destinationDirectory);
|
|
1151
|
+
new EncryptedStorage(NEW_ENCRYPTION_KEY).writeFile(destination, JSON.stringify(nestAccounts({
|
|
1152
|
+
slack: { objectType: 'slack', token: 'old-tok', dCookie: 'old-cookie' },
|
|
1153
|
+
discord: { objectType: 'authorizationBearer', token: 'discord-token' },
|
|
1154
|
+
})));
|
|
1155
|
+
const deps = withStdinKey(NEW_ENCRYPTION_KEY);
|
|
1156
|
+
await runCommand(['auth', 're-encrypt', destinationDirectory], deps);
|
|
1157
|
+
expect(exitCode).toBeNull();
|
|
1158
|
+
const reEncrypted = readWithKey(destination, NEW_ENCRYPTION_KEY);
|
|
1159
|
+
expect(Object.keys(reEncrypted).sort()).toEqual(['discord', 'slack']);
|
|
1160
|
+
expect(reEncrypted.slack).toEqual({
|
|
1161
|
+
objectType: 'slack',
|
|
1162
|
+
token: 'new-tok',
|
|
1163
|
+
dCookie: 'new-cookie',
|
|
1164
|
+
});
|
|
1165
|
+
expect(reEncrypted.discord).toEqual({
|
|
1166
|
+
objectType: 'authorizationBearer',
|
|
1167
|
+
token: 'discord-token',
|
|
1168
|
+
});
|
|
1169
|
+
});
|
|
1170
|
+
it('errors when the existing credential store cannot be read with the new key', async () => {
|
|
1053
1171
|
writeStore({ slack: { objectType: 'slack', token: 'tok', dCookie: 'cookie' } });
|
|
1054
1172
|
const destinationDirectory = join(tempDir, 'export');
|
|
1055
|
-
|
|
1173
|
+
stampDataFormatVersion(destinationDirectory);
|
|
1056
1174
|
const destination = join(destinationDirectory, STORE_FILENAME);
|
|
1057
1175
|
writeFileSync(destination, 'existing');
|
|
1058
1176
|
const deps = withStdinKey(NEW_ENCRYPTION_KEY);
|
|
@@ -1060,6 +1178,36 @@ describe('CLI commands with dependency injection', () => {
|
|
|
1060
1178
|
expect(exitCode).toBe(1);
|
|
1061
1179
|
expect(readFileSync(destination, 'utf-8')).toBe('existing');
|
|
1062
1180
|
});
|
|
1181
|
+
it('re-encrypts the browser state with --browser-state', async () => {
|
|
1182
|
+
writeStore({ slack: { objectType: 'slack', token: 'tok', dCookie: 'cookie' } });
|
|
1183
|
+
new EncryptedStorage(TEST_ENCRYPTION_KEY).writeFile(join(tempDir, BROWSER_STATE_FILENAME), '{"cookies":[]}');
|
|
1184
|
+
const destinationDirectory = join(tempDir, 'export');
|
|
1185
|
+
const deps = withStdinKey(NEW_ENCRYPTION_KEY);
|
|
1186
|
+
await runCommand(['auth', 're-encrypt', destinationDirectory, '--browser-state'], deps);
|
|
1187
|
+
expect(exitCode).toBeNull();
|
|
1188
|
+
const browserStateDestination = join(destinationDirectory, BROWSER_STATE_FILENAME);
|
|
1189
|
+
expect(new EncryptedStorage(NEW_ENCRYPTION_KEY).readFile(browserStateDestination)).toBe('{"cookies":[]}');
|
|
1190
|
+
expect(Object.keys(readWithKey(join(destinationDirectory, STORE_FILENAME), NEW_ENCRYPTION_KEY))).toEqual(['slack']);
|
|
1191
|
+
});
|
|
1192
|
+
it('errors with --browser-state when there is no browser state', async () => {
|
|
1193
|
+
writeStore({ slack: { objectType: 'slack', token: 'tok', dCookie: 'cookie' } });
|
|
1194
|
+
const destinationDirectory = join(tempDir, 'export');
|
|
1195
|
+
const deps = withStdinKey(NEW_ENCRYPTION_KEY);
|
|
1196
|
+
await runCommand(['auth', 're-encrypt', destinationDirectory, '--browser-state'], deps);
|
|
1197
|
+
expect(exitCode).toBe(1);
|
|
1198
|
+
expect(existsSync(join(destinationDirectory, STORE_FILENAME))).toBe(false);
|
|
1199
|
+
});
|
|
1200
|
+
it('overwrites an existing browser state in the destination', async () => {
|
|
1201
|
+
writeStore({});
|
|
1202
|
+
new EncryptedStorage(TEST_ENCRYPTION_KEY).writeFile(join(tempDir, BROWSER_STATE_FILENAME), '{"cookies":["new"]}');
|
|
1203
|
+
const destinationDirectory = join(tempDir, 'export');
|
|
1204
|
+
const browserStateDestination = join(destinationDirectory, BROWSER_STATE_FILENAME);
|
|
1205
|
+
new EncryptedStorage(NEW_ENCRYPTION_KEY).writeFile(browserStateDestination, 'old');
|
|
1206
|
+
const deps = withStdinKey(NEW_ENCRYPTION_KEY);
|
|
1207
|
+
await runCommand(['auth', 're-encrypt', destinationDirectory, '--browser-state'], deps);
|
|
1208
|
+
expect(exitCode).toBeNull();
|
|
1209
|
+
expect(new EncryptedStorage(NEW_ENCRYPTION_KEY).readFile(browserStateDestination)).toBe('{"cookies":["new"]}');
|
|
1210
|
+
});
|
|
1063
1211
|
it('errors when the destination is an existing file, not a directory', async () => {
|
|
1064
1212
|
writeStore({ slack: { objectType: 'slack', token: 'tok', dCookie: 'cookie' } });
|
|
1065
1213
|
const destinationDirectory = join(tempDir, 'export');
|