@huaweidevtools/aishell-dsh-credentials-store 0.0.7 → 0.0.9
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/LICENSE +1 -1
- package/README.md +49 -10
- package/lib/accounts.d.ts +187 -0
- package/lib/accounts.d.ts.map +1 -0
- package/lib/accounts.js +298 -0
- package/lib/accounts.js.map +1 -0
- package/lib/index-JlyJE1E8.d.ts +219 -0
- package/lib/index-JlyJE1E8.d.ts.map +1 -0
- package/lib/index.d.ts +3 -218
- package/lib/index.js +55 -21
- package/lib/index.js.map +1 -1
- package/lib/paths-DtFRzop6.js +46 -0
- package/lib/paths-DtFRzop6.js.map +1 -0
- package/lib/paths.d.ts +56 -0
- package/lib/paths.d.ts.map +1 -0
- package/lib/paths.js +3 -0
- package/lib/scope-CFetnbG3.d.ts +71 -0
- package/lib/scope-CFetnbG3.d.ts.map +1 -0
- package/lib/scope-QmrHZaZt.js +96 -0
- package/lib/scope-QmrHZaZt.js.map +1 -0
- package/lib/scope.d.ts +2 -0
- package/lib/scope.js +3 -0
- package/lib/signer-BPR0UAF0.js +66 -0
- package/lib/signer-BPR0UAF0.js.map +1 -0
- package/lib/signer-Et0DIH6o.d.ts +40 -0
- package/lib/signer-Et0DIH6o.d.ts.map +1 -0
- package/lib/signer.d.ts +2 -40
- package/lib/signer.js +2 -65
- package/lib/types/accounts.d.ts +231 -0
- package/lib/types/accounts.d.ts.map +1 -0
- package/lib/types/accounts.js +384 -0
- package/lib/types/accounts.js.map +1 -0
- package/lib/types/backends/fingerprint.d.ts +41 -0
- package/lib/types/backends/fingerprint.d.ts.map +1 -0
- package/lib/types/backends/fingerprint.js +135 -0
- package/lib/types/backends/fingerprint.js.map +1 -0
- package/lib/types/backends/keyring.d.ts +69 -0
- package/lib/types/backends/keyring.d.ts.map +1 -0
- package/lib/types/backends/keyring.js +107 -0
- package/lib/types/backends/keyring.js.map +1 -0
- package/lib/types/backends/memory.d.ts +45 -0
- package/lib/types/backends/memory.d.ts.map +1 -0
- package/lib/types/backends/memory.js +89 -0
- package/lib/types/backends/memory.js.map +1 -0
- package/lib/types/failover.d.ts +136 -0
- package/lib/types/failover.d.ts.map +1 -0
- package/lib/types/failover.js +242 -0
- package/lib/types/failover.js.map +1 -0
- package/lib/types/index.d.ts +70 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +78 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/paths.d.ts +50 -0
- package/lib/types/paths.d.ts.map +1 -0
- package/lib/types/paths.js +59 -0
- package/lib/types/paths.js.map +1 -0
- package/lib/types/scope.d.ts +65 -0
- package/lib/types/scope.d.ts.map +1 -0
- package/lib/types/scope.js +102 -0
- package/lib/types/scope.js.map +1 -0
- package/lib/types/signer.d.ts +36 -0
- package/lib/types/signer.d.ts.map +1 -0
- package/lib/types/signer.js +81 -0
- package/lib/types/signer.js.map +1 -0
- package/lib/types/verify.d.ts +114 -0
- package/lib/types/verify.d.ts.map +1 -0
- package/lib/types/verify.js +240 -0
- package/lib/types/verify.js.map +1 -0
- package/lib/verify.d.ts +72 -0
- package/lib/verify.d.ts.map +1 -0
- package/lib/verify.js +172 -0
- package/lib/verify.js.map +1 -0
- package/package.json +20 -7
- package/lib/index.d.ts.map +0 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential storage abstraction for aishell DSH plugins.
|
|
3
|
+
*
|
|
4
|
+
* Upper layers (aishell-llm's adapter, aishell-credentials' host half)
|
|
5
|
+
* call {@link createCredentialsStore} and get a {@link CredentialsStore} —
|
|
6
|
+
* they never learn which backend is serving. The factory probes backends in
|
|
7
|
+
* priority order (OS keyring first, process memory last) and returns the
|
|
8
|
+
* first that answers. New backends (fingerprint + encrypted file, etc.) slot
|
|
9
|
+
* into the chain without touching callers. A keyring that answers the probe
|
|
10
|
+
* but later rejects writes fails over to the next backend on first failure.
|
|
11
|
+
*
|
|
12
|
+
* This is a tool library, not a DSH plugin — no `dsh.client`, no
|
|
13
|
+
* `cordis.patch.yml`, no `apply`. DSH's own `ctx.credentials` is untouched;
|
|
14
|
+
* user-configured models and `.credentials.yaml` keep working.
|
|
15
|
+
*
|
|
16
|
+
* @module @huaweidevtools/aishell-dsh-credentials-store
|
|
17
|
+
*/
|
|
18
|
+
/** Options shared by every backend / the factory. */
|
|
19
|
+
export interface CredentialsStoreConfig {
|
|
20
|
+
/**
|
|
21
|
+
* Explicit directory for the fingerprint encrypted-file backend. When set,
|
|
22
|
+
* overrides the default `$DSH_HOME/credentials` resolution. Callers rarely
|
|
23
|
+
* need this — the host's `DSH_HOME` already places credentials alongside
|
|
24
|
+
* its other data.
|
|
25
|
+
*/
|
|
26
|
+
readonly credentialsDir?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Read/write a named credential. Backends are synchronous and per-call — no
|
|
30
|
+
* cache, so a credential changed from outside is visible on the next `get`.
|
|
31
|
+
* Absent credentials read as `undefined` / `has === false`; a backend that
|
|
32
|
+
* cannot serve (e.g. no D-Bus secret service) degrades the same way rather
|
|
33
|
+
* than throwing on read.
|
|
34
|
+
*/
|
|
35
|
+
export interface CredentialsStore {
|
|
36
|
+
/** Read one credential; `undefined` when absent or backend unavailable. */
|
|
37
|
+
get(account: string): string | undefined;
|
|
38
|
+
/** Store one credential. Rejects an empty value; throws on backend errors. */
|
|
39
|
+
set(account: string, value: string): void;
|
|
40
|
+
/** Remove one credential; absent is a no-op. Throws on backend errors. */
|
|
41
|
+
delete(account: string): void;
|
|
42
|
+
/** Whether a credential is currently stored; `false` when absent or backend unavailable. */
|
|
43
|
+
has(account: string): boolean;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Probe backends in priority order and return the first that answers.
|
|
47
|
+
*
|
|
48
|
+
* Priority: OS keyring (durable, cross-process) → machine-fingerprint
|
|
49
|
+
* encrypted file (durable, same-machine) → process memory (volatile,
|
|
50
|
+
* last resort). A backend that cannot initialize — no D-Bus secret service
|
|
51
|
+
* on a headless Linux box, keychain locked, etc. — is skipped, not fatal.
|
|
52
|
+
*
|
|
53
|
+
* A keyring that passes the construction probe but is later found unwritable
|
|
54
|
+
* (GNOME login keyring locked: reads come back null, writes fail — the probe
|
|
55
|
+
* cannot see this) is wrapped in a {@link FailoverStore}: its first failed
|
|
56
|
+
* write fails the whole process over to the fingerprint backend, so saving
|
|
57
|
+
* credentials works instead of erroring. The wrapper also records which
|
|
58
|
+
* accounts the keyring must not answer for, so a credential saved while the
|
|
59
|
+
* collection was locked is not shadowed by the keyring's stale copy once it
|
|
60
|
+
* unlocks.
|
|
61
|
+
*
|
|
62
|
+
* @returns the highest-priority backend that could initialize.
|
|
63
|
+
*/
|
|
64
|
+
export declare function createCredentialsStore(config?: CredentialsStoreConfig): CredentialsStore;
|
|
65
|
+
export { CREDENTIAL_SCOPE, CREDENTIALS_FILE_NAME, DEFAULT_SCOPE, KEYRING_SERVICE } from './scope.ts';
|
|
66
|
+
export { KeyringBackend, __setKeyringModule } from './backends/keyring.ts';
|
|
67
|
+
export { FingerprintBackend } from './backends/fingerprint.ts';
|
|
68
|
+
export { MemoryBackend, __resetSharedMemoryBackend, sharedMemoryBackend } from './backends/memory.ts';
|
|
69
|
+
export { FailoverStore } from './failover.ts';
|
|
70
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAOH,qDAAqD;AACrD,MAAM,WAAW,sBAAsB;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CACjC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2EAA2E;IAC3E,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IACxC,8EAA8E;IAC9E,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACzC,0EAA0E;IAC1E,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,4FAA4F;IAC5F,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAA;CAC9B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,GAAE,sBAA2B,GAAG,gBAAgB,CAe5F;AAiBD,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACpG,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AACrG,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential storage abstraction for aishell DSH plugins.
|
|
3
|
+
*
|
|
4
|
+
* Upper layers (aishell-llm's adapter, aishell-credentials' host half)
|
|
5
|
+
* call {@link createCredentialsStore} and get a {@link CredentialsStore} —
|
|
6
|
+
* they never learn which backend is serving. The factory probes backends in
|
|
7
|
+
* priority order (OS keyring first, process memory last) and returns the
|
|
8
|
+
* first that answers. New backends (fingerprint + encrypted file, etc.) slot
|
|
9
|
+
* into the chain without touching callers. A keyring that answers the probe
|
|
10
|
+
* but later rejects writes fails over to the next backend on first failure.
|
|
11
|
+
*
|
|
12
|
+
* This is a tool library, not a DSH plugin — no `dsh.client`, no
|
|
13
|
+
* `cordis.patch.yml`, no `apply`. DSH's own `ctx.credentials` is untouched;
|
|
14
|
+
* user-configured models and `.credentials.yaml` keep working.
|
|
15
|
+
*
|
|
16
|
+
* @module @huaweidevtools/aishell-dsh-credentials-store
|
|
17
|
+
*/
|
|
18
|
+
import { KeyringBackend } from "./backends/keyring.js";
|
|
19
|
+
import { FingerprintBackend } from "./backends/fingerprint.js";
|
|
20
|
+
import { sharedMemoryBackend } from "./backends/memory.js";
|
|
21
|
+
import { FailoverStore } from "./failover.js";
|
|
22
|
+
/**
|
|
23
|
+
* Probe backends in priority order and return the first that answers.
|
|
24
|
+
*
|
|
25
|
+
* Priority: OS keyring (durable, cross-process) → machine-fingerprint
|
|
26
|
+
* encrypted file (durable, same-machine) → process memory (volatile,
|
|
27
|
+
* last resort). A backend that cannot initialize — no D-Bus secret service
|
|
28
|
+
* on a headless Linux box, keychain locked, etc. — is skipped, not fatal.
|
|
29
|
+
*
|
|
30
|
+
* A keyring that passes the construction probe but is later found unwritable
|
|
31
|
+
* (GNOME login keyring locked: reads come back null, writes fail — the probe
|
|
32
|
+
* cannot see this) is wrapped in a {@link FailoverStore}: its first failed
|
|
33
|
+
* write fails the whole process over to the fingerprint backend, so saving
|
|
34
|
+
* credentials works instead of erroring. The wrapper also records which
|
|
35
|
+
* accounts the keyring must not answer for, so a credential saved while the
|
|
36
|
+
* collection was locked is not shadowed by the keyring's stale copy once it
|
|
37
|
+
* unlocks.
|
|
38
|
+
*
|
|
39
|
+
* @returns the highest-priority backend that could initialize.
|
|
40
|
+
*/
|
|
41
|
+
export function createCredentialsStore(config = {}) {
|
|
42
|
+
const keyring = (() => {
|
|
43
|
+
try {
|
|
44
|
+
return new KeyringBackend(config);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// OS keyring unavailable — try the fingerprint file backend.
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
})();
|
|
51
|
+
if (keyring !== undefined) {
|
|
52
|
+
// FingerprintBackend construction probes machine-id (deriveKey); if that
|
|
53
|
+
// fails, MemoryBackend closes the chain — createFallback never throws.
|
|
54
|
+
return new FailoverStore(keyring, { createFallback: () => createFallbackStore(config) });
|
|
55
|
+
}
|
|
56
|
+
return createFallbackStore(config);
|
|
57
|
+
}
|
|
58
|
+
/** Probe the durable-file and memory backends behind the keyring. */
|
|
59
|
+
function createFallbackStore(config) {
|
|
60
|
+
try {
|
|
61
|
+
return new FingerprintBackend(config);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// Machine fingerprint unavailable (no machine ID) — fall back to memory.
|
|
65
|
+
}
|
|
66
|
+
// The shared instance, not a fresh one: the keyring and the encrypted file
|
|
67
|
+
// are process-external and therefore already common to every caller, while a
|
|
68
|
+
// private Map is not. Four plugins each call the factory, and on a machine
|
|
69
|
+
// with no keyring they must still be reading one store. See
|
|
70
|
+
// `./backends/memory.ts`.
|
|
71
|
+
return sharedMemoryBackend(config);
|
|
72
|
+
}
|
|
73
|
+
export { CREDENTIAL_SCOPE, CREDENTIALS_FILE_NAME, DEFAULT_SCOPE, KEYRING_SERVICE } from "./scope.js";
|
|
74
|
+
export { KeyringBackend, __setKeyringModule } from "./backends/keyring.js";
|
|
75
|
+
export { FingerprintBackend } from "./backends/fingerprint.js";
|
|
76
|
+
export { MemoryBackend, __resetSharedMemoryBackend, sharedMemoryBackend } from "./backends/memory.js";
|
|
77
|
+
export { FailoverStore } from "./failover.js";
|
|
78
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AA+B7C;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAAiC,EAAE;IACxE,MAAM,OAAO,GAAiC,CAAC,GAAG,EAAE;QAClD,IAAI,CAAC;YACH,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,CAAA;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,6DAA6D;YAC7D,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC,CAAC,EAAE,CAAA;IACJ,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,yEAAyE;QACzE,uEAAuE;QACvE,OAAO,IAAI,aAAa,CAAC,OAAO,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAC1F,CAAC;IACD,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAA;AACpC,CAAC;AAED,qEAAqE;AACrE,SAAS,mBAAmB,CAAC,MAA8B;IACzD,IAAI,CAAC;QACH,OAAO,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAA;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,yEAAyE;IAC3E,CAAC;IACD,2EAA2E;IAC3E,6EAA6E;IAC7E,2EAA2E;IAC3E,4DAA4D;IAC5D,0BAA0B;IAC1B,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAA;AACpC,CAAC;AAED,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACpG,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AACrG,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where per-host state lives. One definition, shared.
|
|
3
|
+
*
|
|
4
|
+
* ## Why this lives in the store package
|
|
5
|
+
*
|
|
6
|
+
* `DSH_HOME` is the host's data directory, and two things in this repo derive
|
|
7
|
+
* from it: the encrypted credentials file here, and the terraform cache in
|
|
8
|
+
* `aishell-deploy`. Defining it twice would let the two drift — the same
|
|
9
|
+
* failure shape the credential-scope constant was created to end.
|
|
10
|
+
*
|
|
11
|
+
* The direction is forced by the dependency graph: `aishell-deploy` already
|
|
12
|
+
* depends on this package, so a definition here is reachable from there, while
|
|
13
|
+
* the reverse would be a cycle. This module is the lower of the two, so it is
|
|
14
|
+
* where the definition belongs.
|
|
15
|
+
*
|
|
16
|
+
* @module @huaweidevtools/aishell-dsh-credentials-store/paths
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* The fallback data directory when the host sets no `DSH_HOME`.
|
|
20
|
+
*
|
|
21
|
+
* `~/.aishell` — the same directory the desktop app uses, so a library or
|
|
22
|
+
* headless run shares one location with a real install rather than inventing a
|
|
23
|
+
* second home directory.
|
|
24
|
+
*/
|
|
25
|
+
export declare const FALLBACK_HOME_NAME = ".aishell";
|
|
26
|
+
/**
|
|
27
|
+
* The host's data directory.
|
|
28
|
+
*
|
|
29
|
+
* `DSH_HOME` when the host set it — the desktop app and the CLI both do, so
|
|
30
|
+
* this lands where the rest of that host's data lives — otherwise
|
|
31
|
+
* `~/.aishell`.
|
|
32
|
+
*
|
|
33
|
+
* Read per call, never captured: a host that sets `DSH_HOME` after this module
|
|
34
|
+
* is first imported must still be honoured.
|
|
35
|
+
*
|
|
36
|
+
* @returns the base directory; not created here.
|
|
37
|
+
*/
|
|
38
|
+
export declare function dshHome(): string;
|
|
39
|
+
/**
|
|
40
|
+
* The directory holding the encrypted credentials file.
|
|
41
|
+
*
|
|
42
|
+
* `<DSH_HOME>/credentials`. Builds are separated by the *file name* (the
|
|
43
|
+
* credential scope — `plugins.credentials.enc` by default), not by a second
|
|
44
|
+
* directory, so two builds sit side by side here without reading each other's
|
|
45
|
+
* secrets.
|
|
46
|
+
*
|
|
47
|
+
* @returns the directory; not created here.
|
|
48
|
+
*/
|
|
49
|
+
export declare function credentialsDir(): string;
|
|
50
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,aAAa,CAAA;AAE5C;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,IAAI,MAAM,CAIhC;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where per-host state lives. One definition, shared.
|
|
3
|
+
*
|
|
4
|
+
* ## Why this lives in the store package
|
|
5
|
+
*
|
|
6
|
+
* `DSH_HOME` is the host's data directory, and two things in this repo derive
|
|
7
|
+
* from it: the encrypted credentials file here, and the terraform cache in
|
|
8
|
+
* `aishell-deploy`. Defining it twice would let the two drift — the same
|
|
9
|
+
* failure shape the credential-scope constant was created to end.
|
|
10
|
+
*
|
|
11
|
+
* The direction is forced by the dependency graph: `aishell-deploy` already
|
|
12
|
+
* depends on this package, so a definition here is reachable from there, while
|
|
13
|
+
* the reverse would be a cycle. This module is the lower of the two, so it is
|
|
14
|
+
* where the definition belongs.
|
|
15
|
+
*
|
|
16
|
+
* @module @huaweidevtools/aishell-dsh-credentials-store/paths
|
|
17
|
+
*/
|
|
18
|
+
import { homedir } from 'node:os';
|
|
19
|
+
import { join } from 'node:path';
|
|
20
|
+
/**
|
|
21
|
+
* The fallback data directory when the host sets no `DSH_HOME`.
|
|
22
|
+
*
|
|
23
|
+
* `~/.aishell` — the same directory the desktop app uses, so a library or
|
|
24
|
+
* headless run shares one location with a real install rather than inventing a
|
|
25
|
+
* second home directory.
|
|
26
|
+
*/
|
|
27
|
+
export const FALLBACK_HOME_NAME = '.aishell';
|
|
28
|
+
/**
|
|
29
|
+
* The host's data directory.
|
|
30
|
+
*
|
|
31
|
+
* `DSH_HOME` when the host set it — the desktop app and the CLI both do, so
|
|
32
|
+
* this lands where the rest of that host's data lives — otherwise
|
|
33
|
+
* `~/.aishell`.
|
|
34
|
+
*
|
|
35
|
+
* Read per call, never captured: a host that sets `DSH_HOME` after this module
|
|
36
|
+
* is first imported must still be honoured.
|
|
37
|
+
*
|
|
38
|
+
* @returns the base directory; not created here.
|
|
39
|
+
*/
|
|
40
|
+
export function dshHome() {
|
|
41
|
+
const configured = process.env.DSH_HOME;
|
|
42
|
+
if (configured !== undefined && configured.trim() !== '')
|
|
43
|
+
return configured;
|
|
44
|
+
return join(homedir(), FALLBACK_HOME_NAME);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The directory holding the encrypted credentials file.
|
|
48
|
+
*
|
|
49
|
+
* `<DSH_HOME>/credentials`. Builds are separated by the *file name* (the
|
|
50
|
+
* credential scope — `plugins.credentials.enc` by default), not by a second
|
|
51
|
+
* directory, so two builds sit side by side here without reading each other's
|
|
52
|
+
* secrets.
|
|
53
|
+
*
|
|
54
|
+
* @returns the directory; not created here.
|
|
55
|
+
*/
|
|
56
|
+
export function credentialsDir() {
|
|
57
|
+
return join(dshHome(), 'credentials');
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAA;AAE5C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,OAAO;IACrB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAA;IACvC,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,UAAU,CAAA;IAC3E,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,CAAA;AAC5C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAA;AACvC,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which credential namespace this build uses.
|
|
3
|
+
*
|
|
4
|
+
* ## The knob
|
|
5
|
+
*
|
|
6
|
+
* A build-time constant, not a runtime setting:
|
|
7
|
+
*
|
|
8
|
+
* ```sh
|
|
9
|
+
* AISHELL_CREDENTIAL_SCOPE=staging pnpm run build
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* Default `plugins`. It decides two things, and it decides both at once —
|
|
13
|
+
* which is the point:
|
|
14
|
+
*
|
|
15
|
+
* | Used as | Default |
|
|
16
|
+
* |---|---|
|
|
17
|
+
* | keyring service name | `aishell-dsh-plugins` |
|
|
18
|
+
* | encrypted file name | `plugins.credentials.enc` |
|
|
19
|
+
*
|
|
20
|
+
* ## Why it is not a plugin config option
|
|
21
|
+
*
|
|
22
|
+
* It was one, briefly: `keyringService` sat on four plugins' `Config`. Only one
|
|
23
|
+
* of the four writes and all four read, so a deployment that set it on a reader
|
|
24
|
+
* but not the writer stored credentials in one namespace and looked for them in
|
|
25
|
+
* another — the form said "saved" while every tool said "not authenticated".
|
|
26
|
+
* A knob whose only observable effect is that failure is not worth having.
|
|
27
|
+
*
|
|
28
|
+
* A constant cannot be set on one side only. Two deployments that must not see
|
|
29
|
+
* each other's credentials (a staging profile beside a production one) differ
|
|
30
|
+
* by *building* differently, which is the honest place for a persistence
|
|
31
|
+
* boundary.
|
|
32
|
+
*
|
|
33
|
+
* ## Why there is no migration
|
|
34
|
+
*
|
|
35
|
+
* The default changed from `aishell-dsh` to `aishell-dsh-plugins` before the
|
|
36
|
+
* first release, so no install ever wrote the old namespace. Nothing reads it,
|
|
37
|
+
* and adding a migration path would mean keeping the old name alive forever for
|
|
38
|
+
* a state that never existed.
|
|
39
|
+
*
|
|
40
|
+
* @module @huaweidevtools/aishell-dsh-credentials-store/scope
|
|
41
|
+
*/
|
|
42
|
+
/**
|
|
43
|
+
* The default scope.
|
|
44
|
+
*
|
|
45
|
+
* Named for the repository, not for a feature: the credential store is shared
|
|
46
|
+
* by every plugin in this set, so it is not `llm`'s or `e2b`'s.
|
|
47
|
+
*/
|
|
48
|
+
export declare const DEFAULT_SCOPE = "plugins";
|
|
49
|
+
/** The scope this build uses. */
|
|
50
|
+
export declare const CREDENTIAL_SCOPE: string;
|
|
51
|
+
/**
|
|
52
|
+
* The keyring service every entry of this build lives under.
|
|
53
|
+
*
|
|
54
|
+
* Part of the persistence contract: renaming it orphans every stored entry
|
|
55
|
+
* while looking like a harmless constant change.
|
|
56
|
+
*/
|
|
57
|
+
export declare const KEYRING_SERVICE: string;
|
|
58
|
+
/**
|
|
59
|
+
* The encrypted file name for this build.
|
|
60
|
+
*
|
|
61
|
+
* Scoped the same way as the keyring service, so two builds on one machine
|
|
62
|
+
* cannot collide in either backend.
|
|
63
|
+
*/
|
|
64
|
+
export declare const CREDENTIALS_FILE_NAME: string;
|
|
65
|
+
//# sourceMappingURL=scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,aAAa,YAAY,CAAA;AAkDtC,iCAAiC;AACjC,eAAO,MAAM,gBAAgB,QAAiB,CAAA;AAE9C;;;;;GAKG;AACH,eAAO,MAAM,eAAe,QAAoC,CAAA;AAEhE;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,QAAwC,CAAA"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which credential namespace this build uses.
|
|
3
|
+
*
|
|
4
|
+
* ## The knob
|
|
5
|
+
*
|
|
6
|
+
* A build-time constant, not a runtime setting:
|
|
7
|
+
*
|
|
8
|
+
* ```sh
|
|
9
|
+
* AISHELL_CREDENTIAL_SCOPE=staging pnpm run build
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* Default `plugins`. It decides two things, and it decides both at once —
|
|
13
|
+
* which is the point:
|
|
14
|
+
*
|
|
15
|
+
* | Used as | Default |
|
|
16
|
+
* |---|---|
|
|
17
|
+
* | keyring service name | `aishell-dsh-plugins` |
|
|
18
|
+
* | encrypted file name | `plugins.credentials.enc` |
|
|
19
|
+
*
|
|
20
|
+
* ## Why it is not a plugin config option
|
|
21
|
+
*
|
|
22
|
+
* It was one, briefly: `keyringService` sat on four plugins' `Config`. Only one
|
|
23
|
+
* of the four writes and all four read, so a deployment that set it on a reader
|
|
24
|
+
* but not the writer stored credentials in one namespace and looked for them in
|
|
25
|
+
* another — the form said "saved" while every tool said "not authenticated".
|
|
26
|
+
* A knob whose only observable effect is that failure is not worth having.
|
|
27
|
+
*
|
|
28
|
+
* A constant cannot be set on one side only. Two deployments that must not see
|
|
29
|
+
* each other's credentials (a staging profile beside a production one) differ
|
|
30
|
+
* by *building* differently, which is the honest place for a persistence
|
|
31
|
+
* boundary.
|
|
32
|
+
*
|
|
33
|
+
* ## Why there is no migration
|
|
34
|
+
*
|
|
35
|
+
* The default changed from `aishell-dsh` to `aishell-dsh-plugins` before the
|
|
36
|
+
* first release, so no install ever wrote the old namespace. Nothing reads it,
|
|
37
|
+
* and adding a migration path would mean keeping the old name alive forever for
|
|
38
|
+
* a state that never existed.
|
|
39
|
+
*
|
|
40
|
+
* @module @huaweidevtools/aishell-dsh-credentials-store/scope
|
|
41
|
+
*/
|
|
42
|
+
/**
|
|
43
|
+
* The default scope.
|
|
44
|
+
*
|
|
45
|
+
* Named for the repository, not for a feature: the credential store is shared
|
|
46
|
+
* by every plugin in this set, so it is not `llm`'s or `e2b`'s.
|
|
47
|
+
*/
|
|
48
|
+
export const DEFAULT_SCOPE = 'plugins';
|
|
49
|
+
/**
|
|
50
|
+
* Accepted scope shape: a lowercase identifier.
|
|
51
|
+
*
|
|
52
|
+
* The value reaches a keyring service name and a file name, so it is validated
|
|
53
|
+
* as a strict identifier rather than merely "not obviously a path": no
|
|
54
|
+
* separators, no dots, no leading dash. Assuming a value is benign because the
|
|
55
|
+
* caller is trusted is how path traversal gets in.
|
|
56
|
+
*/
|
|
57
|
+
const SCOPE_PATTERN = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
58
|
+
/**
|
|
59
|
+
* Resolve the scope for this build.
|
|
60
|
+
*
|
|
61
|
+
* Fails loudly on a malformed value rather than falling back to the default:
|
|
62
|
+
* a typo would otherwise silently share the namespace with every unset build,
|
|
63
|
+
* which is exactly the confusion scoping exists to avoid.
|
|
64
|
+
*
|
|
65
|
+
* @returns the validated scope.
|
|
66
|
+
* @throws when the injected value is not a valid scope.
|
|
67
|
+
*/
|
|
68
|
+
function resolveScope() {
|
|
69
|
+
// `typeof` rather than a direct read: an undeclared identifier throws, and a
|
|
70
|
+
// source run legitimately has no injected value.
|
|
71
|
+
const injected = typeof __AISHELL_CREDENTIAL_SCOPE__ === 'string'
|
|
72
|
+
? __AISHELL_CREDENTIAL_SCOPE__
|
|
73
|
+
: undefined;
|
|
74
|
+
if (injected === undefined || injected === '')
|
|
75
|
+
return DEFAULT_SCOPE;
|
|
76
|
+
const normalized = injected.trim().toLowerCase();
|
|
77
|
+
if (normalized.length === 0)
|
|
78
|
+
return DEFAULT_SCOPE;
|
|
79
|
+
if (!SCOPE_PATTERN.test(normalized)) {
|
|
80
|
+
throw new Error(`AISHELL_CREDENTIAL_SCOPE=${JSON.stringify(injected)} is not a valid credential scope: `
|
|
81
|
+
+ `expected 1-64 characters of [a-z0-9_-], starting with a letter or digit `
|
|
82
|
+
+ '(for example "plugins" or "staging").');
|
|
83
|
+
}
|
|
84
|
+
return normalized;
|
|
85
|
+
}
|
|
86
|
+
/** The scope this build uses. */
|
|
87
|
+
export const CREDENTIAL_SCOPE = resolveScope();
|
|
88
|
+
/**
|
|
89
|
+
* The keyring service every entry of this build lives under.
|
|
90
|
+
*
|
|
91
|
+
* Part of the persistence contract: renaming it orphans every stored entry
|
|
92
|
+
* while looking like a harmless constant change.
|
|
93
|
+
*/
|
|
94
|
+
export const KEYRING_SERVICE = `aishell-dsh-${CREDENTIAL_SCOPE}`;
|
|
95
|
+
/**
|
|
96
|
+
* The encrypted file name for this build.
|
|
97
|
+
*
|
|
98
|
+
* Scoped the same way as the keyring service, so two builds on one machine
|
|
99
|
+
* cannot collide in either backend.
|
|
100
|
+
*/
|
|
101
|
+
export const CREDENTIALS_FILE_NAME = `${CREDENTIAL_SCOPE}.credentials.enc`;
|
|
102
|
+
//# sourceMappingURL=scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,SAAS,CAAA;AAWtC;;;;;;;GAOG;AACH,MAAM,aAAa,GAAG,4BAA4B,CAAA;AAElD;;;;;;;;;GASG;AACH,SAAS,YAAY;IACnB,6EAA6E;IAC7E,iDAAiD;IACjD,MAAM,QAAQ,GAAG,OAAO,4BAA4B,KAAK,QAAQ;QAC/D,CAAC,CAAC,4BAA4B;QAC9B,CAAC,CAAC,SAAS,CAAA;IACb,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE;QAAE,OAAO,aAAa,CAAA;IACnE,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IAChD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,aAAa,CAAA;IACjD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CACb,4BAA4B,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,oCAAoC;cACtF,0EAA0E;cAC1E,uCAAuC,CAC1C,CAAA;IACH,CAAC;IACD,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,iCAAiC;AACjC,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,EAAE,CAAA;AAE9C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,eAAe,gBAAgB,EAAE,CAAA;AAEhE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,gBAAgB,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Huawei Cloud SDK-HMAC-SHA256 request signing.
|
|
3
|
+
*
|
|
4
|
+
* Signs an HTTP request with AK/SK (and an optional temporary SecurityToken)
|
|
5
|
+
* using the same algorithm as the official Huawei Cloud SDK. Produces the
|
|
6
|
+
* `Authorization`, `x-sdk-date`, and `x-security-token` headers to attach
|
|
7
|
+
* to a `fetch` call.
|
|
8
|
+
*
|
|
9
|
+
* @module @huaweidevtools/aishell-dsh-credentials-store/signer
|
|
10
|
+
*/
|
|
11
|
+
/** Credentials for signing. */
|
|
12
|
+
export interface SignCredentials {
|
|
13
|
+
readonly ak: string;
|
|
14
|
+
readonly sk: string;
|
|
15
|
+
readonly securityToken?: string;
|
|
16
|
+
}
|
|
17
|
+
/** The headers produced by {@link sign}. */
|
|
18
|
+
export interface SignedHeaders {
|
|
19
|
+
readonly host: string;
|
|
20
|
+
readonly 'x-sdk-date': string;
|
|
21
|
+
readonly Authorization: string;
|
|
22
|
+
readonly 'x-security-token'?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Sign an HTTP request with SDK-HMAC-SHA256.
|
|
26
|
+
*
|
|
27
|
+
* @param method - HTTP method (GET, POST, ...).
|
|
28
|
+
* @param host - Host component of the request URL (e.g. `openai.aishell.openbuildlab.com`).
|
|
29
|
+
* @param path - Path component of the request URL (e.g. `/chat/completions`).
|
|
30
|
+
* @param query - Query parameters as a key-value map.
|
|
31
|
+
* @param body - Request body (stringified for hashing; empty string for GET).
|
|
32
|
+
* @param credentials - AK/SK and optional SecurityToken.
|
|
33
|
+
* @returns The headers to attach to the fetch call.
|
|
34
|
+
*/
|
|
35
|
+
export declare function sign(method: string, host: string, path: string, query: Record<string, string>, body: string, credentials: SignCredentials): SignedHeaders;
|
|
36
|
+
//# sourceMappingURL=signer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../src/signer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,+BAA+B;AAC/B,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAChC;AAED,4CAA4C;AAC5C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CACrC;AAiCD;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAClB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,eAAe,GAC3B,aAAa,CAoCf"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Huawei Cloud SDK-HMAC-SHA256 request signing.
|
|
3
|
+
*
|
|
4
|
+
* Signs an HTTP request with AK/SK (and an optional temporary SecurityToken)
|
|
5
|
+
* using the same algorithm as the official Huawei Cloud SDK. Produces the
|
|
6
|
+
* `Authorization`, `x-sdk-date`, and `x-security-token` headers to attach
|
|
7
|
+
* to a `fetch` call.
|
|
8
|
+
*
|
|
9
|
+
* @module @huaweidevtools/aishell-dsh-credentials-store/signer
|
|
10
|
+
*/
|
|
11
|
+
import crypto from 'node:crypto';
|
|
12
|
+
function sha256Hex(data) {
|
|
13
|
+
return crypto.createHash('sha256').update(data).digest('hex');
|
|
14
|
+
}
|
|
15
|
+
function hmacSha256(key, data) {
|
|
16
|
+
return crypto.createHmac('sha256', key).update(data).digest('hex');
|
|
17
|
+
}
|
|
18
|
+
/** RFC 3986 URL-encode a string (unreserved chars stay literal). */
|
|
19
|
+
function urlEncode(str) {
|
|
20
|
+
const hex = (c) => '%' + (c < 16 ? '0' : '') + c.toString(16).toUpperCase();
|
|
21
|
+
const noEscape = new Set('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~'.split(''));
|
|
22
|
+
let out = '';
|
|
23
|
+
for (const ch of str) {
|
|
24
|
+
const c = ch.codePointAt(0);
|
|
25
|
+
if (c < 0x80) {
|
|
26
|
+
out += noEscape.has(ch) ? ch : hex(c);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
out += encodeURIComponent(ch);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
/** ISO 8601 timestamp in Huawei Cloud format: `20260912T064552Z`. */
|
|
35
|
+
function sdkTimestamp() {
|
|
36
|
+
// toISOString() returns "2026-09-12T06:45:52.123Z"; strip separators and
|
|
37
|
+
// milliseconds but keep the trailing Z — do NOT append another one.
|
|
38
|
+
return new Date().toISOString().replace(/[-:]/g, '').replace(/\.\d+/, '');
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Sign an HTTP request with SDK-HMAC-SHA256.
|
|
42
|
+
*
|
|
43
|
+
* @param method - HTTP method (GET, POST, ...).
|
|
44
|
+
* @param host - Host component of the request URL (e.g. `openai.aishell.openbuildlab.com`).
|
|
45
|
+
* @param path - Path component of the request URL (e.g. `/chat/completions`).
|
|
46
|
+
* @param query - Query parameters as a key-value map.
|
|
47
|
+
* @param body - Request body (stringified for hashing; empty string for GET).
|
|
48
|
+
* @param credentials - AK/SK and optional SecurityToken.
|
|
49
|
+
* @returns The headers to attach to the fetch call.
|
|
50
|
+
*/
|
|
51
|
+
export function sign(method, host, path, query, body, credentials) {
|
|
52
|
+
const ts = sdkTimestamp();
|
|
53
|
+
// Canonical query string (sorted keys)
|
|
54
|
+
const cqs = Object.entries(query)
|
|
55
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
56
|
+
.map(([k, v]) => `${urlEncode(k)}=${urlEncode(v)}`)
|
|
57
|
+
.join('&');
|
|
58
|
+
// Canonical URI: path segments URL-encoded, joined with /, trailing /
|
|
59
|
+
const curi = '/' + path.split('/').filter(Boolean).map(urlEncode).join('/') + '/';
|
|
60
|
+
// Signed headers
|
|
61
|
+
const hasToken = credentials.securityToken !== undefined;
|
|
62
|
+
const signedHeaders = hasToken ? 'host;x-sdk-date;x-security-token' : 'host;x-sdk-date';
|
|
63
|
+
const canonicalHeaders = hasToken
|
|
64
|
+
? `host:${host}\nx-sdk-date:${ts}\nx-security-token:${credentials.securityToken}\n`
|
|
65
|
+
: `host:${host}\nx-sdk-date:${ts}\n`;
|
|
66
|
+
// Payload hash
|
|
67
|
+
const payloadHash = sha256Hex(body);
|
|
68
|
+
// Canonical request
|
|
69
|
+
const canonicalRequest = [method, curi, cqs, canonicalHeaders, signedHeaders, payloadHash].join('\n');
|
|
70
|
+
// String to sign
|
|
71
|
+
const stringToSign = `SDK-HMAC-SHA256\n${ts}\n${sha256Hex(canonicalRequest)}`;
|
|
72
|
+
const signature = hmacSha256(credentials.sk, stringToSign);
|
|
73
|
+
const headers = {
|
|
74
|
+
host,
|
|
75
|
+
'x-sdk-date': ts,
|
|
76
|
+
Authorization: `SDK-HMAC-SHA256 Access=${credentials.ak}, SignedHeaders=${signedHeaders}, Signature=${signature}`,
|
|
77
|
+
...(hasToken ? { 'x-security-token': credentials.securityToken } : {}),
|
|
78
|
+
};
|
|
79
|
+
return headers;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=signer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signer.js","sourceRoot":"","sources":["../../src/signer.ts"],"names":[],"mappings":"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"}
|