tiny-http-mcp-server 0.1.61 → 0.1.63
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/composition.json +1 -1
- package/node_modules/auth-store/README.md +3 -1
- package/node_modules/auth-store/dist/encrypted-file-store.js +1 -0
- package/node_modules/auth-store/dist/transaction-lock.js +1 -0
- package/node_modules/mcp-oauth/README.md +8 -3
- package/node_modules/mcp-oauth/dist/client/auth-store-session-store.js +4 -2
- package/node_modules/mcp-oauth/dist/client/default-oauth-client-provider.js +2 -1
- package/node_modules/mcp-oauth/dist/client/token-grant.js +1 -0
- package/node_modules/tiny-mcp-client/dist/index.js +7 -3
- package/package.json +1 -1
package/dist/composition.json
CHANGED
|
@@ -34,7 +34,9 @@ for transactions spanning a read, external operation and write. Independent
|
|
|
34
34
|
instances and processes serialize the same encrypted file or Keychain
|
|
35
35
|
service/account; unrelated identities proceed independently. The default
|
|
36
36
|
acquisition timeout is 30 seconds. Cancellation during acquisition does not
|
|
37
|
-
release the active owner's lock.
|
|
37
|
+
release the active owner's lock. Each acquisition retains its original signal
|
|
38
|
+
and timeout before path checks wait; replacing the caller's option handles cannot
|
|
39
|
+
bypass original cancellation or introduce another signal's cancellation. Individual `get`, `set` and `delete` calls do
|
|
38
40
|
not implicitly acquire it.
|
|
39
41
|
|
|
40
42
|
Locks use private filesystem claim directories, containing PID/random names
|
|
@@ -81,6 +81,7 @@ export class EncryptedFileStore {
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
async withLock(operation, options = {}) {
|
|
84
|
+
options = { ...options };
|
|
84
85
|
await this.assertCredentialPathHasNoSymbolicLinks(`${this.filePath}.lock`);
|
|
85
86
|
if (this.fs.readdir === undefined)
|
|
86
87
|
throw new Error("Secret-store transaction locks require filesystem readdir support");
|
|
@@ -3,6 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import { hasOwnErrorCode } from "./error-codes.js";
|
|
4
4
|
/** Filesystem bakery lock: unique claims allow dead-owner cleanup without deleting a replacement owner's lock. */
|
|
5
5
|
export async function withSecretStoreFileLock(fs, lockDirectory, operation, options = {}) {
|
|
6
|
+
options = { ...options };
|
|
6
7
|
const timeoutMs = options.timeoutMs ?? 30_000;
|
|
7
8
|
if (!Number.isFinite(timeoutMs) || timeoutMs < 0 || timeoutMs > 2_147_483_647)
|
|
8
9
|
throw new Error("Invalid secret-store transaction lock timeout");
|
|
@@ -64,7 +64,8 @@ aborting the original signal still cancels authorization.
|
|
|
64
64
|
Native session and client persistence factories also capture file paths, salts,
|
|
65
65
|
Keychain identities, lock locations and selected filesystem/command handles.
|
|
66
66
|
Mutating these settings cannot redirect a later read or write.
|
|
67
|
-
The factories
|
|
67
|
+
The factories copy these settings before reading the selected backend environment
|
|
68
|
+
variable, so its getter cannot replace them. They resolve that variable once at creation;
|
|
68
69
|
later environment changes cannot move a transaction between file and Keychain.
|
|
69
70
|
|
|
70
71
|
`createJwksTokenVerifier(options)` accepts:
|
|
@@ -157,9 +158,13 @@ used only for its resource.
|
|
|
157
158
|
Discovery binds an expired or explicitly rejected grant before silent refresh,
|
|
158
159
|
using the original configured client. Persisted sessions take precedence,
|
|
159
160
|
including sessions whose tokens have been cleared; an import cannot revive them.
|
|
160
|
-
Input tokens are copied
|
|
161
|
+
Input tokens are copied before any host clock anchors a relative lifetime;
|
|
162
|
+
clock mutation cannot replace the selected access/refresh/scope values. Invalid
|
|
163
|
+
expiry values fail before authorization.
|
|
161
164
|
For a raw OAuth response, `parseOAuthTokenGrant(response, { issuedAt, expiresAt })`
|
|
162
|
-
returns normalized `StoredOAuthTokens`.
|
|
165
|
+
returns normalized `StoredOAuthTokens`. Timing options are captured before the
|
|
166
|
+
host clock runs, so it cannot bypass their earlier validation. The parser accepts
|
|
167
|
+
`access_token`, `refresh_token`,
|
|
163
168
|
`token_type`, `scope`, `expires_in` (seconds), `expires_at` (epoch seconds), and
|
|
164
169
|
`expiresAt` (epoch milliseconds). Numeric absolute expiry wins over relative
|
|
165
170
|
lifetime; the options timestamp wins over response timestamps. The optional
|
|
@@ -82,12 +82,14 @@ export function createAuthStoreClientStore(options, namespace) {
|
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
84
|
function snapshotPersistenceOptions(options) {
|
|
85
|
-
|
|
86
|
-
...options,
|
|
85
|
+
const snapshot = {
|
|
86
|
+
...options,
|
|
87
87
|
...(options.fileStore === undefined ? {} : { fileStore: { ...options.fileStore } }),
|
|
88
88
|
...(options.keychainStore === undefined ? {} : { keychainStore: { ...options.keychainStore,
|
|
89
89
|
...(options.keychainStore.lock === undefined ? {} : { lock: { ...options.keychainStore.lock } }) } })
|
|
90
90
|
};
|
|
91
|
+
snapshot.backend = resolveSecretStoreBackend(snapshot);
|
|
92
|
+
return snapshot;
|
|
91
93
|
}
|
|
92
94
|
export function createNamedSecretStore(key, options, defaults, namespace) {
|
|
93
95
|
const hash = crypto.createHash("sha256").update(namespace === undefined ? key : JSON.stringify([namespace, key])).digest("hex");
|
|
@@ -603,6 +603,7 @@ function normalizeImportedTokens(value, now) {
|
|
|
603
603
|
const absolute = getOwnEntry(value, "expiresAt");
|
|
604
604
|
const lifetime = getOwnEntry(value, "expiresIn");
|
|
605
605
|
const issuedAt = getOwnEntry(value, "issuedAt");
|
|
606
|
+
const snapshot = { ...value };
|
|
606
607
|
if (lifetime !== undefined && (typeof lifetime !== "number" || !Number.isSafeInteger(lifetime) || lifetime < 0))
|
|
607
608
|
throw new Error("OAuth initial grant has invalid relative expiry");
|
|
608
609
|
if (issuedAt !== undefined && (typeof issuedAt !== "number" || !Number.isSafeInteger(issuedAt) ||
|
|
@@ -610,7 +611,7 @@ function normalizeImportedTokens(value, now) {
|
|
|
610
611
|
throw new Error("OAuth initial grant has invalid issuance time");
|
|
611
612
|
const expiresAt = absolute !== undefined && absolute !== null ? absolute :
|
|
612
613
|
lifetime === undefined ? null : (issuedAt === undefined ? now() : issuedAt) + lifetime * 1000;
|
|
613
|
-
return normalizeStoredTokens({ ...
|
|
614
|
+
return normalizeStoredTokens({ ...snapshot, expiresAt });
|
|
614
615
|
}
|
|
615
616
|
function normalizeStoredTokens(value) {
|
|
616
617
|
if (value === undefined || !isObjectRecord(value)) {
|
|
@@ -2,6 +2,7 @@ import { copyBoundedOAuthJson } from "./bounded-json.js";
|
|
|
2
2
|
import { normalizeOAuthScope } from "./scope.js";
|
|
3
3
|
/** Validate a raw RFC token response and anchor its lifetime once for persistence. */
|
|
4
4
|
export function parseOAuthTokenGrant(value, options = {}) {
|
|
5
|
+
options = { ...options };
|
|
5
6
|
const invalid = () => new Error("Invalid OAuth token grant");
|
|
6
7
|
const result = copyBoundedOAuthJson(value, "Invalid OAuth token grant");
|
|
7
8
|
if (typeof result !== "object" || result === null || Array.isArray(result))
|
|
@@ -3907,6 +3907,7 @@ function hasOwnErrorCode(error, code) {
|
|
|
3907
3907
|
import { randomUUID } from "node:crypto";
|
|
3908
3908
|
import path from "node:path";
|
|
3909
3909
|
async function withSecretStoreFileLock(fs2, lockDirectory, operation, options = {}) {
|
|
3910
|
+
options = { ...options };
|
|
3910
3911
|
const timeoutMs = options.timeoutMs ?? 3e4;
|
|
3911
3912
|
if (!Number.isFinite(timeoutMs) || timeoutMs < 0 || timeoutMs > 2147483647)
|
|
3912
3913
|
throw new Error("Invalid secret-store transaction lock timeout");
|
|
@@ -4126,6 +4127,7 @@ var EncryptedFileStore = class {
|
|
|
4126
4127
|
}
|
|
4127
4128
|
}
|
|
4128
4129
|
async withLock(operation, options = {}) {
|
|
4130
|
+
options = { ...options };
|
|
4129
4131
|
await this.assertCredentialPathHasNoSymbolicLinks(`${this.filePath}.lock`);
|
|
4130
4132
|
if (this.fs.readdir === void 0)
|
|
4131
4133
|
throw new Error("Secret-store transaction locks require filesystem readdir support");
|
|
@@ -4638,15 +4640,16 @@ function createAuthStoreClientStore(options, namespace) {
|
|
|
4638
4640
|
};
|
|
4639
4641
|
}
|
|
4640
4642
|
function snapshotPersistenceOptions(options) {
|
|
4641
|
-
|
|
4643
|
+
const snapshot = {
|
|
4642
4644
|
...options,
|
|
4643
|
-
backend: resolveSecretStoreBackend(options),
|
|
4644
4645
|
...options.fileStore === void 0 ? {} : { fileStore: { ...options.fileStore } },
|
|
4645
4646
|
...options.keychainStore === void 0 ? {} : { keychainStore: {
|
|
4646
4647
|
...options.keychainStore,
|
|
4647
4648
|
...options.keychainStore.lock === void 0 ? {} : { lock: { ...options.keychainStore.lock } }
|
|
4648
4649
|
} }
|
|
4649
4650
|
};
|
|
4651
|
+
snapshot.backend = resolveSecretStoreBackend(snapshot);
|
|
4652
|
+
return snapshot;
|
|
4650
4653
|
}
|
|
4651
4654
|
function createNamedSecretStore(key2, options, defaults, namespace) {
|
|
4652
4655
|
const hash = crypto2.createHash("sha256").update(namespace === void 0 ? key2 : JSON.stringify([namespace, key2])).digest("hex");
|
|
@@ -5834,12 +5837,13 @@ function normalizeImportedTokens(value, now) {
|
|
|
5834
5837
|
const absolute = getOwnEntry6(value, "expiresAt");
|
|
5835
5838
|
const lifetime = getOwnEntry6(value, "expiresIn");
|
|
5836
5839
|
const issuedAt = getOwnEntry6(value, "issuedAt");
|
|
5840
|
+
const snapshot = { ...value };
|
|
5837
5841
|
if (lifetime !== void 0 && (typeof lifetime !== "number" || !Number.isSafeInteger(lifetime) || lifetime < 0))
|
|
5838
5842
|
throw new Error("OAuth initial grant has invalid relative expiry");
|
|
5839
5843
|
if (issuedAt !== void 0 && (typeof issuedAt !== "number" || !Number.isSafeInteger(issuedAt) || Math.abs(issuedAt) > MAX_JS_DATE_MS3))
|
|
5840
5844
|
throw new Error("OAuth initial grant has invalid issuance time");
|
|
5841
5845
|
const expiresAt = absolute !== void 0 && absolute !== null ? absolute : lifetime === void 0 ? null : (issuedAt === void 0 ? now() : issuedAt) + lifetime * 1e3;
|
|
5842
|
-
return normalizeStoredTokens({ ...
|
|
5846
|
+
return normalizeStoredTokens({ ...snapshot, expiresAt });
|
|
5843
5847
|
}
|
|
5844
5848
|
function normalizeStoredTokens(value) {
|
|
5845
5849
|
if (value === void 0 || !isObjectRecord3(value)) {
|