latchkey 3.13.1 → 3.14.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/README.md +18 -1
- package/dist/src/cliCommands.d.ts.map +1 -1
- package/dist/src/cliCommands.js +29 -9
- package/dist/src/cliCommands.js.map +1 -1
- package/dist/src/curlInjection.d.ts +13 -4
- package/dist/src/curlInjection.d.ts.map +1 -1
- package/dist/src/curlInjection.js +10 -6
- package/dist/src/curlInjection.js.map +1 -1
- package/dist/src/errorMessages.d.ts.map +1 -1
- package/dist/src/errorMessages.js +35 -1
- package/dist/src/errorMessages.js.map +1 -1
- package/dist/src/gateway/gatewayEndpoint.d.ts.map +1 -1
- package/dist/src/gateway/gatewayEndpoint.js +10 -4
- package/dist/src/gateway/gatewayEndpoint.js.map +1 -1
- package/dist/src/gateway/headerEncoding.d.ts +22 -0
- package/dist/src/gateway/headerEncoding.d.ts.map +1 -0
- package/dist/src/gateway/headerEncoding.js +26 -0
- package/dist/src/gateway/headerEncoding.js.map +1 -0
- package/dist/src/gateway/server.d.ts.map +1 -1
- package/dist/src/gateway/server.js +4 -1
- package/dist/src/gateway/server.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/tests/cli.test.js +65 -0
- package/dist/tests/cli.test.js.map +1 -1
- package/dist/tests/errorMessages.test.d.ts +6 -0
- package/dist/tests/errorMessages.test.d.ts.map +1 -0
- package/dist/tests/errorMessages.test.js +31 -0
- package/dist/tests/errorMessages.test.js.map +1 -0
- package/dist/tests/gateway.test.js +40 -0
- package/dist/tests/gateway.test.js.map +1 -1
- package/dist/tests/headerEncoding.test.d.ts +5 -0
- package/dist/tests/headerEncoding.test.d.ts.map +1 -0
- package/dist/tests/headerEncoding.test.js +40 -0
- package/dist/tests/headerEncoding.test.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recovering the original text of HTTP header values.
|
|
3
|
+
*
|
|
4
|
+
* Node's HTTP parser hands header values back as latin-1: each byte on the
|
|
5
|
+
* wire becomes one character, so a UTF-8 value arrives mojibake'd (an account
|
|
6
|
+
* named `Jane’s Space` reads as `Janeâs Space`). Clients send
|
|
7
|
+
* UTF-8 — curl writes the bytes of its argument verbatim — so the gateway has
|
|
8
|
+
* to undo that decoding before comparing a value against anything it holds as
|
|
9
|
+
* real text, such as a stored account or the configured password.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Re-interpret a header value that Node decoded as latin-1 as the UTF-8 it
|
|
13
|
+
* almost certainly was.
|
|
14
|
+
*
|
|
15
|
+
* The conversion is applied only when it round-trips: re-encoding the result
|
|
16
|
+
* must reproduce the exact bytes received. That leaves a pure-ASCII value
|
|
17
|
+
* untouched (ASCII is its own UTF-8), and leaves a value whose bytes are not
|
|
18
|
+
* valid UTF-8 exactly as received rather than replacing the offending bytes
|
|
19
|
+
* with U+FFFD.
|
|
20
|
+
*/
|
|
21
|
+
export declare function decodeHeaderValue(value: string): string;
|
|
22
|
+
//# sourceMappingURL=headerEncoding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headerEncoding.d.ts","sourceRoot":"","sources":["../../../src/gateway/headerEncoding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIvD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recovering the original text of HTTP header values.
|
|
3
|
+
*
|
|
4
|
+
* Node's HTTP parser hands header values back as latin-1: each byte on the
|
|
5
|
+
* wire becomes one character, so a UTF-8 value arrives mojibake'd (an account
|
|
6
|
+
* named `Jane’s Space` reads as `Janeâs Space`). Clients send
|
|
7
|
+
* UTF-8 — curl writes the bytes of its argument verbatim — so the gateway has
|
|
8
|
+
* to undo that decoding before comparing a value against anything it holds as
|
|
9
|
+
* real text, such as a stored account or the configured password.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Re-interpret a header value that Node decoded as latin-1 as the UTF-8 it
|
|
13
|
+
* almost certainly was.
|
|
14
|
+
*
|
|
15
|
+
* The conversion is applied only when it round-trips: re-encoding the result
|
|
16
|
+
* must reproduce the exact bytes received. That leaves a pure-ASCII value
|
|
17
|
+
* untouched (ASCII is its own UTF-8), and leaves a value whose bytes are not
|
|
18
|
+
* valid UTF-8 exactly as received rather than replacing the offending bytes
|
|
19
|
+
* with U+FFFD.
|
|
20
|
+
*/
|
|
21
|
+
export function decodeHeaderValue(value) {
|
|
22
|
+
const bytes = Buffer.from(value, 'latin1');
|
|
23
|
+
const decoded = bytes.toString('utf8');
|
|
24
|
+
return Buffer.from(decoded, 'utf8').equals(bytes) ? decoded : value;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=headerEncoding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headerEncoding.js","sourceRoot":"","sources":["../../../src/gateway/headerEncoding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvC,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AACtE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/gateway/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/gateway/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,sBAAsB,CAAC;AA8D9B,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAkDD;;GAEG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,eAAe,EACrB,kBAAkB,EAAE,kBAAkB,EACtC,gBAAgB,EAAE,gBAAgB,EAClC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CAyJxB"}
|
|
@@ -8,6 +8,7 @@ import * as http from 'node:http';
|
|
|
8
8
|
import { ErrorMessages } from '../errorMessages.js';
|
|
9
9
|
import { extractTargetUrl, GATEWAY_PATH_PREFIX, handleGatewayRequest, } from './gatewayEndpoint.js';
|
|
10
10
|
import { handleLatchkeyRequest } from './latchkeyEndpoint.js';
|
|
11
|
+
import { decodeHeaderValue } from './headerEncoding.js';
|
|
11
12
|
import { GATEWAY_PASSWORD_HEADER, passwordsMatch } from './password.js';
|
|
12
13
|
import { createServiceRegistry } from '../serviceRegistry.js';
|
|
13
14
|
import { dispatchExtensionRequest, loadExtensions, startExtensions, stopExtensions, } from './extensions.js';
|
|
@@ -19,11 +20,13 @@ function sendErrorResponse(response, statusCode, message) {
|
|
|
19
20
|
/**
|
|
20
21
|
* Read a single header value, treating arrays (which Node returns for some
|
|
21
22
|
* headers) as missing because the password header is not allowed to repeat.
|
|
23
|
+
* The value is decoded out of Node's latin-1 rendering so that a password
|
|
24
|
+
* containing non-ASCII characters compares equal to the configured one.
|
|
22
25
|
*/
|
|
23
26
|
function readSingleHeader(request, headerName) {
|
|
24
27
|
const value = request.headers[headerName];
|
|
25
28
|
if (typeof value === 'string')
|
|
26
|
-
return value;
|
|
29
|
+
return decodeHeaderValue(value);
|
|
27
30
|
return undefined;
|
|
28
31
|
}
|
|
29
32
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/gateway/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAIlC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,GAErB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EACL,wBAAwB,EACxB,cAAc,EACd,eAAe,EACf,cAAc,GAEf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,+BAA+B,EAC/B,mCAAmC,EACnC,+BAA+B,GAChC,MAAM,0BAA0B,CAAC;AAElC,SAAS,iBAAiB,CACxB,QAA6B,EAC7B,UAAkB,EAClB,OAAe;IAEf,QAAQ,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACvE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACxE,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/gateway/server.ts"],"names":[],"mappings":"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"}
|
package/dist/src/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "3.
|
|
1
|
+
export declare const VERSION = "3.14.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/src/version.js
CHANGED
package/dist/tests/cli.test.js
CHANGED
|
@@ -808,6 +808,16 @@ describe('CLI commands with dependency injection', () => {
|
|
|
808
808
|
expect(errorLogs.join('\n')).toContain("No credentials found for slack (account 'missing@example.com')");
|
|
809
809
|
expect(errorLogs.join('\n')).toContain('latchkey --account missing@example.com auth browser slack');
|
|
810
810
|
});
|
|
811
|
+
it('shell-quotes an account that needs it in the suggested commands', async () => {
|
|
812
|
+
// A Notion account is named after its workspace, so it routinely holds
|
|
813
|
+
// spaces and typographic punctuation. The suggested commands have to
|
|
814
|
+
// survive a copy-paste into the shell.
|
|
815
|
+
writeMultiAccountStore({ 'jane@example.com:Jane\u2019s Space': 'workspace' });
|
|
816
|
+
const deps = createMockDependencies();
|
|
817
|
+
await runCommand(['--account', 'Jane\u2019s Space', 'curl', 'https://slack.com/api/test'], deps);
|
|
818
|
+
expect(exitCode).toBe(1);
|
|
819
|
+
expect(errorLogs.join('\n')).toContain('latchkey --account "Jane\u2019s Space" auth browser slack');
|
|
820
|
+
});
|
|
811
821
|
it('auth clear keeps the preparation without --all', async () => {
|
|
812
822
|
const storePath = join(tempDir, 'credentials.json');
|
|
813
823
|
writeSecureFile(storePath, JSON.stringify({
|
|
@@ -887,6 +897,61 @@ describe('CLI commands with dependency injection', () => {
|
|
|
887
897
|
expect(errorLogs.join('\n')).toContain('--account option is not supported');
|
|
888
898
|
});
|
|
889
899
|
});
|
|
900
|
+
describe('--dry-run option', () => {
|
|
901
|
+
it('curl reports the injecting service instead of sending the request', async () => {
|
|
902
|
+
const storePath = join(tempDir, 'credentials.json');
|
|
903
|
+
writeSecureFile(storePath, JSON.stringify(nestAccounts({
|
|
904
|
+
slack: { objectType: 'slack', token: 'stored-token', dCookie: 'stored-cookie' },
|
|
905
|
+
})));
|
|
906
|
+
const deps = createMockDependencies();
|
|
907
|
+
await runCommand(['--dry-run', 'curl', 'https://slack.com/api/test'], deps);
|
|
908
|
+
expect(exitCode).toBe(0);
|
|
909
|
+
expect(capturedArgs).toEqual([]);
|
|
910
|
+
expect(logs).toHaveLength(1);
|
|
911
|
+
expect(JSON.parse(logs[0] ?? '')).toEqual({
|
|
912
|
+
credentialsInjected: true,
|
|
913
|
+
service: 'slack',
|
|
914
|
+
});
|
|
915
|
+
});
|
|
916
|
+
it('curl reports no injection for a passed-through request', async () => {
|
|
917
|
+
const deps = createMockDependencies({
|
|
918
|
+
config: createMockConfig({ passthroughUnknown: true }),
|
|
919
|
+
});
|
|
920
|
+
await runCommand(['--dry-run', 'curl', 'https://unknown-api.example.com/test'], deps);
|
|
921
|
+
expect(exitCode).toBe(0);
|
|
922
|
+
expect(capturedArgs).toEqual([]);
|
|
923
|
+
expect(JSON.parse(logs[0] ?? '')).toEqual({
|
|
924
|
+
credentialsInjected: false,
|
|
925
|
+
service: null,
|
|
926
|
+
});
|
|
927
|
+
});
|
|
928
|
+
it('curl still fails when no credentials can be injected', async () => {
|
|
929
|
+
const deps = createMockDependencies();
|
|
930
|
+
await runCommand(['--dry-run', 'curl', 'https://slack.com/api/test'], deps);
|
|
931
|
+
expect(exitCode).toBe(1);
|
|
932
|
+
expect(logs).toHaveLength(0);
|
|
933
|
+
expect(capturedArgs).toEqual([]);
|
|
934
|
+
});
|
|
935
|
+
it('rejects --dry-run in gateway mode', async () => {
|
|
936
|
+
const deps = createMockDependencies({
|
|
937
|
+
config: createMockConfig({ gatewayUrl: 'http://localhost:9000' }),
|
|
938
|
+
});
|
|
939
|
+
await runCommand(['--dry-run', 'curl', 'https://slack.com/api/test'], deps);
|
|
940
|
+
expect(exitCode).toBe(1);
|
|
941
|
+
expect(capturedArgs).toEqual([]);
|
|
942
|
+
expect(errorLogs.join('\n')).toContain('--dry-run option is not supported in gateway mode');
|
|
943
|
+
});
|
|
944
|
+
it.each([
|
|
945
|
+
['auth', 'list'],
|
|
946
|
+
['services', 'list'],
|
|
947
|
+
['auth', 'set', 'slack', '-H', 'X-Token: secret'],
|
|
948
|
+
])('rejects --dry-run for the unsupported command: %s %s', async (...commandArgs) => {
|
|
949
|
+
const deps = createMockDependencies();
|
|
950
|
+
await runCommand(['--dry-run', ...commandArgs], deps);
|
|
951
|
+
expect(exitCode).toBe(1);
|
|
952
|
+
expect(errorLogs.join('\n')).toContain('--dry-run option is not supported');
|
|
953
|
+
});
|
|
954
|
+
});
|
|
890
955
|
describe('auth list command', () => {
|
|
891
956
|
it('should list stored credentials with their status', async () => {
|
|
892
957
|
const storePath = join(tempDir, 'credentials.json');
|