Auth hardening CI gaps + SDK consolidation: EMA leg 2 / scopes (#1527) (#1725)
Some checks failed
Run install, format, lint, build, and test on every push / build (push) Has been cancelled
Run install, format, lint, build, and test on every push / publish (push) Has been cancelled
Run install, format, lint, build, and test on every push / publish-github-container-registry (push) Has been cancelled
Some checks failed
Run install, format, lint, build, and test on every push / build (push) Has been cancelled
Run install, format, lint, build, and test on every push / publish (push) Has been cancelled
Run install, format, lint, build, and test on every push / publish-github-container-registry (push) Has been cancelled
Close #1527 acceptance gaps with automated tests (SEP-2468 iss, SEP-2207 offline_access, SEP-2351 discovery shapes, SEP-2352 AS-migration, EraNegotiationFailed→401 unwrap); lean EMA leg 2 and scope helpers on the v2 SDK; drop deprecated TS baseUrl. Reviewed LGTM.
This commit is contained in:
parent
ec185f1053
commit
a71e6d2012
1 changed files with 1513 additions and 852 deletions
|
|
@ -1,46 +1,22 @@
|
|||
/**
|
||||
* SEP-2350 scope helpers aligned with v2 `@modelcontextprotocol/client` exports.
|
||||
* On SDK v2 upgrade, delete this module and import `computeScopeUnion` /
|
||||
* `isStrictScopeSuperset` from the client package instead.
|
||||
* SEP-2350 scope helpers. Union / strict-superset algorithms come from
|
||||
* `@modelcontextprotocol/client`; Inspector-only persistence helpers stay local.
|
||||
*/
|
||||
|
||||
import {
|
||||
parseScopeString,
|
||||
unionAuthorizationScopes,
|
||||
} from "./challenge.js";
|
||||
computeScopeUnion as sdkComputeScopeUnion,
|
||||
isStrictScopeSuperset as sdkIsStrictScopeSuperset,
|
||||
} from "@modelcontextprotocol/client";
|
||||
|
||||
/** Union space-delimited scope strings (order-preserving, deduped). */
|
||||
export function computeScopeUnion(
|
||||
...scopes: ReadonlyArray<string | undefined>
|
||||
): string | undefined {
|
||||
let merged: string | undefined;
|
||||
for (const scope of scopes) {
|
||||
merged = unionAuthorizationScopes(merged, parseScopeString(scope)).join(
|
||||
" ",
|
||||
);
|
||||
if (!merged) {
|
||||
merged = undefined;
|
||||
}
|
||||
}
|
||||
return merged;
|
||||
}
|
||||
export const computeScopeUnion = sdkComputeScopeUnion;
|
||||
|
||||
/**
|
||||
* Whether `union` contains a scope token not present in `current`.
|
||||
* When the AS omits `scope` on the token response, `current` is empty and any
|
||||
* non-empty union is a strict superset — step-up must re-authorize, not refresh.
|
||||
*/
|
||||
export function isStrictScopeSuperset(
|
||||
union: string | undefined,
|
||||
current: string | undefined,
|
||||
): boolean {
|
||||
if (!union) return false;
|
||||
const currentSet = new Set((current ?? "").split(/\s+/).filter(Boolean));
|
||||
for (const token of union.split(/\s+/)) {
|
||||
if (token && !currentSet.has(token)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
export const isStrictScopeSuperset = sdkIsStrictScopeSuperset;
|
||||
|
||||
/**
|
||||
* Scope to persist after a successful token grant (RFC 6749 §5.1).
|
||||
|
|
|
|||
Loading…
Reference in a new issue