@schemavaults/auth-common 0.23.0 → 0.24.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.
@@ -2,3 +2,4 @@ export { OIDC_OPENID_SCOPE, OIDC_SUPPORTED_SCOPES, DEFAULT_AUTH_SCOPE, OIDC_SCOP
2
2
  export type { OidcSupportedScope, OidcScope, ParsedOidcScopes, } from "./scope";
3
3
  export { oidcNonceSchema, OIDC_NONCE_VSCHAR_REGEX, parseOidcNonce, OidcNonceValidationError, } from "./nonce";
4
4
  export type { OidcNonce } from "./nonce";
5
+ export { OIDC_SUB_CLAIM_DELIMITER, formatOidcSubClaim, parseOidcSubClaim, } from "./sub-claim";
@@ -1,3 +1,4 @@
1
1
  export { OIDC_OPENID_SCOPE, OIDC_SUPPORTED_SCOPES, DEFAULT_AUTH_SCOPE, OIDC_SCOPE_REGEX, oidcScopeSchema, parseAndGrantScopes, serializeOidcScopes, } from "./scope";
2
2
  export { oidcNonceSchema, OIDC_NONCE_VSCHAR_REGEX, parseOidcNonce, OidcNonceValidationError, } from "./nonce";
3
+ export { OIDC_SUB_CLAIM_DELIMITER, formatOidcSubClaim, parseOidcSubClaim, } from "./sub-claim";
3
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/oidc/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AAOjB,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,cAAc,EACd,wBAAwB,GACzB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/oidc/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AAOjB,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,cAAc,EACd,wBAAwB,GACzB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,aAAa,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { type AppId } from "@schemavaults/app-definitions";
2
+ export declare const OIDC_SUB_CLAIM_DELIMITER: "|";
3
+ /**
4
+ * Builds the OIDC-facing `sub` claim for a platform user:
5
+ * `<auth_server_app_id>|<uid>`. The auth server app id is stable per
6
+ * deployment, so the resulting subject is stable for the lifetime of
7
+ * the user (OIDC Core §2: `sub` must be locally unique and never
8
+ * reassigned within the issuer).
9
+ */
10
+ export declare function formatOidcSubClaim(auth_server_app_id: AppId | string, uid: string): string;
11
+ /**
12
+ * Splits an OIDC-facing `sub` claim back into the issuing deployment's
13
+ * app id and the platform user id. Returns `null` for values not in the
14
+ * `<app_id>|<uid>` shape (e.g. subjects issued by other providers).
15
+ * Only the FIRST delimiter splits — the uid keeps any later characters
16
+ * verbatim.
17
+ */
18
+ export declare function parseOidcSubClaim(sub: string): {
19
+ auth_server_app_id: AppId;
20
+ uid: string;
21
+ } | null;
@@ -0,0 +1,57 @@
1
+ import { appIdSchema } from "@schemavaults/app-definitions";
2
+ // The OIDC-facing `sub` claim namespaces the platform user id with the
3
+ // deployment's own app id (SCHEMAVAULTS_AUTH_SERVER_APP_ID), Auth0-style:
4
+ // `<auth_server_app_id>|<uid>` (e.g. "schemavaults-auth|4f7c…"). The
5
+ // prefix marks which auth deployment a subject came from, so RPs that
6
+ // aggregate identities from several issuers / white-label deployments
7
+ // can't collide or confuse them. It applies ONLY at the OIDC boundary —
8
+ // the id_token, /api/oidc/userinfo, and RFC 7662 introspection, which
9
+ // OIDC Core §5.3.2 requires to agree exactly — never inside the
10
+ // platform's own encrypted access/refresh token payloads, whose
11
+ // `sub === uid` invariant (payload_data.ts) resource servers rely on.
12
+ // The app id charset ([a-z0-9_-]) can never contain the delimiter, so
13
+ // the encoding is unambiguous.
14
+ export const OIDC_SUB_CLAIM_DELIMITER = "|";
15
+ /**
16
+ * Builds the OIDC-facing `sub` claim for a platform user:
17
+ * `<auth_server_app_id>|<uid>`. The auth server app id is stable per
18
+ * deployment, so the resulting subject is stable for the lifetime of
19
+ * the user (OIDC Core §2: `sub` must be locally unique and never
20
+ * reassigned within the issuer).
21
+ */
22
+ export function formatOidcSubClaim(auth_server_app_id, uid) {
23
+ const app_id = appIdSchema.safeParse(auth_server_app_id);
24
+ if (!app_id.success) {
25
+ throw new TypeError("Invalid auth server app id for OIDC 'sub' claim prefix!", { cause: app_id.error });
26
+ }
27
+ if (typeof uid !== "string" || uid.length === 0) {
28
+ throw new TypeError("A user id is required to build an OIDC 'sub' claim!");
29
+ }
30
+ return `${app_id.data}${OIDC_SUB_CLAIM_DELIMITER}${uid}`;
31
+ }
32
+ /**
33
+ * Splits an OIDC-facing `sub` claim back into the issuing deployment's
34
+ * app id and the platform user id. Returns `null` for values not in the
35
+ * `<app_id>|<uid>` shape (e.g. subjects issued by other providers).
36
+ * Only the FIRST delimiter splits — the uid keeps any later characters
37
+ * verbatim.
38
+ */
39
+ export function parseOidcSubClaim(sub) {
40
+ if (typeof sub !== "string") {
41
+ return null;
42
+ }
43
+ const delimiter_index = sub.indexOf(OIDC_SUB_CLAIM_DELIMITER);
44
+ if (delimiter_index <= 0) {
45
+ return null;
46
+ }
47
+ const app_id = appIdSchema.safeParse(sub.slice(0, delimiter_index));
48
+ if (!app_id.success) {
49
+ return null;
50
+ }
51
+ const uid = sub.slice(delimiter_index + OIDC_SUB_CLAIM_DELIMITER.length);
52
+ if (uid.length === 0) {
53
+ return null;
54
+ }
55
+ return { auth_server_app_id: app_id.data, uid };
56
+ }
57
+ //# sourceMappingURL=sub-claim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sub-claim.js","sourceRoot":"","sources":["../../src/oidc/sub-claim.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAc,MAAM,+BAA+B,CAAC;AAExE,uEAAuE;AACvE,0EAA0E;AAC1E,qEAAqE;AACrE,sEAAsE;AACtE,sEAAsE;AACtE,wEAAwE;AACxE,sEAAsE;AACtE,gEAAgE;AAChE,gEAAgE;AAChE,sEAAsE;AACtE,sEAAsE;AACtE,+BAA+B;AAE/B,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAY,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,kBAAkC,EAClC,GAAW;IAEX,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;IACzD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,SAAS,CACjB,yDAAyD,EACzD,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CACxB,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,SAAS,CAAC,qDAAqD,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,GAAG,MAAM,CAAC,IAAI,GAAG,wBAAwB,GAAG,GAAG,EAAE,CAAC;AAC3D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAW;IAEX,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,eAAe,GAAG,GAAG,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC9D,IAAI,eAAe,IAAI,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC;IACpE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,eAAe,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAC;IACzE,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,EAAE,kBAAkB,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC;AAClD,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@schemavaults/auth-common",
3
3
  "description": "Types and utility functions for authentication and authorization",
4
- "version": "0.23.0",
4
+ "version": "0.24.0",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
7
7
  "repository": {