@ai-matrx/auth 0.3.7 → 0.3.8

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/CHANGELOG.md CHANGED
@@ -1,10 +1,19 @@
1
1
  # Changelog — @ai-matrx/auth
2
2
 
3
- ## 0.3.7
3
+ ### Unreleased
4
+
5
+ - **New subpath `@ai-matrx/auth/claims`; `/credentials` gains `sessionCredentials` / `userCredentials` (2026-10-17).** The claims read (`getClaimsUser`, `createClaimsCache`, the signing-key pins and refusal tests) and the session -> credential mapping (moved to `src/session-credentials.ts`, still re-exported by the root) without the root, so a sibling's server-side entry (`@ai-matrx/data` `/db`, `/access`, `/script`, `/short-link`) never imports `@ai-matrx/auth` whole. Additive; the root's exports are unchanged. Consumer action: none.
6
+
7
+ ## 0.3.8
4
8
 
5
9
  UNVERIFIED: this release has no Unreleased entry and the source comparison could not be made (the caller supplied no source comparison). Whether source changed is unknown; consumer action is unknown.
6
10
  Check the package's gitHead on npm against this version's gitHead: `git diff <previous gitHead> <this gitHead> -- apps/shared/auth/src`.
7
11
 
12
+ ## 0.3.7
13
+
14
+ Automatic changed-only republish (docs/metadata drift since the last published version; verified: `git diff cd85c8a24f 02e0da3204 -- apps/shared/auth/src`
15
+ has no shipped-source changes outside tests, fixtures and docs). No consumer action required.
16
+
8
17
  ## 0.3.6
9
18
  ### Unreleased
10
19
  - New `@ai-matrx/auth/browser` (`createBrowserSupabase`, shared code path with `createNextSupabase().browserClient()`).
@@ -68,41 +68,7 @@ declare function signInWithOAuth(client: AuthClient, options: {
68
68
  declare function signOut(client: AuthClient, scope?: "global" | "local" | "others"): Promise<void>;
69
69
  /** Change the signed-in person's email, phone, password or metadata. */
70
70
  declare function updatePerson(client: AuthClient, attributes: UserAttributes): Promise<User>;
71
- /** The slice of a client the session credential reads: its `auth`, when it has one. */
72
- interface SessionSourceLike {
73
- auth?: {
74
- getSession(): PromiseLike<{
75
- data: {
76
- session: {
77
- access_token: string;
78
- } | null;
79
- };
80
- }>;
81
- onAuthStateChange(cb: (event: string, session: unknown) => void): {
82
- data: {
83
- subscription: {
84
- unsubscribe(): void;
85
- };
86
- };
87
- };
88
- } | undefined;
89
- }
90
- /** The `user` credential port (structural; the shape `@ai-matrx/api`'s `CredentialsPort` takes). */
91
- interface UserCredentialsPort {
92
- get(): Promise<{
93
- kind: "user";
94
- accessToken: string;
95
- } | null>;
96
- onChange?(cb: () => void): () => void;
97
- }
98
- /**
99
- * THE ONE session → credential mapping: the current access token as api's `user` credential,
100
- * re-read on every call (a refresh rotates it), with `onChange` on every session change.
101
- * A client with no `auth` is anonymous (null), never an error.
102
- */
103
- declare function sessionCredentials(client: SessionSourceLike): UserCredentialsPort;
104
- /** The session as `@ai-matrx/api`'s `user` credential — the name `@ai-matrx/data/auth` shipped. */
105
- declare const userCredentials: typeof sessionCredentials;
71
+
106
72
  /**
107
73
  * Refresh the session now (a long-lived script, a desktop app waking from sleep, a tab that was
108
74
  * frozen). Returns the new session; throws `SignInError` when the refresh token is refused.
@@ -653,4 +619,4 @@ declare function storageHeldOrganization(storage: Pick<Storage, "getItem" | "set
653
619
  declare function memoryHeldOrganization(): HeldOrganizationStore;
654
620
  declare function createActiveOrganization(options: CreateActiveOrganizationOptions): ActiveOrganization;
655
621
 
656
- export { createNotAMemberRefusalNotice as $, type AuthClient as A, NoActiveOrganizationError as B, type CachedActiveOrganization as C, NotAMemberError as D, type NotAMemberRefusalNotice as E, ORGANIZATION_ENTITY_TYPE as F, ORGANIZATION_RESOLUTION_TIMEOUT_MS as G, type HeldOrganizationStore as H, type OrganizationBootstrapGate as I, type OrganizationLapse as J, type OrganizationMembership as K, LINK_ORGANIZATION_QUERY_KEY as L, type OrganizationRefusal as M, NOT_A_MEMBER_RECHECK_GAP_MS as N, type OrganizationsDb as O, type OrganizationRung as P, type ParentOrganization as Q, type ReadMembershipsOptions as R, type SessionSourceLike as S, type ResolveWithLinkInput as T, type UserCredentialsPort as U, type ResolvedOrganization as V, type ResolvedWithLink as W, adminSeatReplacesUserContext as X, classifyLinkOrganizationValue as Y, classifyOrganizationRefusal as Z, createActiveOrganization as _, SignInError as a, createOrganizationBootstrapGate as a0, decideLinkOrganization as a1, isNotAMemberRefusal as a2, linkOrganizationMalformedMessage as a3, linkOrganizationNotAMemberMessage as a4, linkOrganizationOfferMessage as a5, linkOrganizationSwitchAnnouncement as a6, memoryHeldOrganization as a7, oldestMembership as a8, orderOrganizations as a9, organizationMatches as aa, readAccountOrganizationChoices as ab, readLinkOrganizationParam as ac, readMemberships as ad, readOrganizationFavourites as ae, resolveActiveOrganization as af, resolveActiveOrganizationLazily as ag, resolveAdminSeat as ah, resolveChildOrganizationId as ai, resolveOrganizationWithLink as aj, setOrganizationFavourite as ak, storageHeldOrganization as al, toAccountOrganizationChoices as am, writeLastActiveOrganization as an, writeStartupOrganization as ao, getSession as b, signInWithOAuth as c, signInWithPassword as d, signOut as e, userCredentials as f, getPerson as g, type AccountOrganizationChoices as h, invalidatePerson as i, type ActiveOrganization as j, type ActiveOrganizationSnapshot as k, type ActiveOrganizationStatus as l, type AdminSeat as m, type AdminSeatInput as n, onSessionChange as o, type ArchiveFilter as p, type CreateActiveOrganizationOptions as q, refreshSession as r, sessionCredentials as s, type LadderInput as t, updatePerson as u, type LinkOrganizationDecision as v, type LinkOrganizationDecisionInput as w, type LinkOrganizationMembership as x, type LinkOrganizationMessages as y, type LinkOrganizationParam as z };
622
+ export { linkOrganizationMalformedMessage as $, type AuthClient as A, ORGANIZATION_ENTITY_TYPE as B, type CachedActiveOrganization as C, ORGANIZATION_RESOLUTION_TIMEOUT_MS as D, type OrganizationBootstrapGate as E, type OrganizationLapse as F, type OrganizationMembership as G, type HeldOrganizationStore as H, type OrganizationRefusal as I, type OrganizationRung as J, type ResolveWithLinkInput as K, LINK_ORGANIZATION_QUERY_KEY as L, type ResolvedOrganization as M, NOT_A_MEMBER_RECHECK_GAP_MS as N, type OrganizationsDb as O, type ParentOrganization as P, type ResolvedWithLink as Q, type ReadMembershipsOptions as R, SignInError as S, adminSeatReplacesUserContext as T, classifyLinkOrganizationValue as U, classifyOrganizationRefusal as V, createActiveOrganization as W, createNotAMemberRefusalNotice as X, createOrganizationBootstrapGate as Y, decideLinkOrganization as Z, isNotAMemberRefusal as _, getSession as a, linkOrganizationNotAMemberMessage as a0, linkOrganizationOfferMessage as a1, linkOrganizationSwitchAnnouncement as a2, memoryHeldOrganization as a3, oldestMembership as a4, orderOrganizations as a5, organizationMatches as a6, readAccountOrganizationChoices as a7, readLinkOrganizationParam as a8, readMemberships as a9, readOrganizationFavourites as aa, resolveActiveOrganization as ab, resolveActiveOrganizationLazily as ac, resolveAdminSeat as ad, resolveChildOrganizationId as ae, resolveOrganizationWithLink as af, setOrganizationFavourite as ag, storageHeldOrganization as ah, toAccountOrganizationChoices as ai, writeLastActiveOrganization as aj, writeStartupOrganization as ak, signInWithPassword as b, signOut as c, type AccountOrganizationChoices as d, type ActiveOrganization as e, type ActiveOrganizationSnapshot as f, getPerson as g, type ActiveOrganizationStatus as h, invalidatePerson as i, type AdminSeat as j, type AdminSeatInput as k, type ArchiveFilter as l, type CreateActiveOrganizationOptions as m, type LadderInput as n, onSessionChange as o, type LinkOrganizationDecision as p, type LinkOrganizationDecisionInput as q, refreshSession as r, signInWithOAuth as s, type LinkOrganizationMembership as t, updatePerson as u, type LinkOrganizationMessages as v, type LinkOrganizationParam as w, NoActiveOrganizationError as x, NotAMemberError as y, type NotAMemberRefusalNotice as z };
@@ -68,41 +68,7 @@ declare function signInWithOAuth(client: AuthClient, options: {
68
68
  declare function signOut(client: AuthClient, scope?: "global" | "local" | "others"): Promise<void>;
69
69
  /** Change the signed-in person's email, phone, password or metadata. */
70
70
  declare function updatePerson(client: AuthClient, attributes: UserAttributes): Promise<User>;
71
- /** The slice of a client the session credential reads: its `auth`, when it has one. */
72
- interface SessionSourceLike {
73
- auth?: {
74
- getSession(): PromiseLike<{
75
- data: {
76
- session: {
77
- access_token: string;
78
- } | null;
79
- };
80
- }>;
81
- onAuthStateChange(cb: (event: string, session: unknown) => void): {
82
- data: {
83
- subscription: {
84
- unsubscribe(): void;
85
- };
86
- };
87
- };
88
- } | undefined;
89
- }
90
- /** The `user` credential port (structural; the shape `@ai-matrx/api`'s `CredentialsPort` takes). */
91
- interface UserCredentialsPort {
92
- get(): Promise<{
93
- kind: "user";
94
- accessToken: string;
95
- } | null>;
96
- onChange?(cb: () => void): () => void;
97
- }
98
- /**
99
- * THE ONE session → credential mapping: the current access token as api's `user` credential,
100
- * re-read on every call (a refresh rotates it), with `onChange` on every session change.
101
- * A client with no `auth` is anonymous (null), never an error.
102
- */
103
- declare function sessionCredentials(client: SessionSourceLike): UserCredentialsPort;
104
- /** The session as `@ai-matrx/api`'s `user` credential — the name `@ai-matrx/data/auth` shipped. */
105
- declare const userCredentials: typeof sessionCredentials;
71
+
106
72
  /**
107
73
  * Refresh the session now (a long-lived script, a desktop app waking from sleep, a tab that was
108
74
  * frozen). Returns the new session; throws `SignInError` when the refresh token is refused.
@@ -653,4 +619,4 @@ declare function storageHeldOrganization(storage: Pick<Storage, "getItem" | "set
653
619
  declare function memoryHeldOrganization(): HeldOrganizationStore;
654
620
  declare function createActiveOrganization(options: CreateActiveOrganizationOptions): ActiveOrganization;
655
621
 
656
- export { createNotAMemberRefusalNotice as $, type AuthClient as A, NoActiveOrganizationError as B, type CachedActiveOrganization as C, NotAMemberError as D, type NotAMemberRefusalNotice as E, ORGANIZATION_ENTITY_TYPE as F, ORGANIZATION_RESOLUTION_TIMEOUT_MS as G, type HeldOrganizationStore as H, type OrganizationBootstrapGate as I, type OrganizationLapse as J, type OrganizationMembership as K, LINK_ORGANIZATION_QUERY_KEY as L, type OrganizationRefusal as M, NOT_A_MEMBER_RECHECK_GAP_MS as N, type OrganizationsDb as O, type OrganizationRung as P, type ParentOrganization as Q, type ReadMembershipsOptions as R, type SessionSourceLike as S, type ResolveWithLinkInput as T, type UserCredentialsPort as U, type ResolvedOrganization as V, type ResolvedWithLink as W, adminSeatReplacesUserContext as X, classifyLinkOrganizationValue as Y, classifyOrganizationRefusal as Z, createActiveOrganization as _, SignInError as a, createOrganizationBootstrapGate as a0, decideLinkOrganization as a1, isNotAMemberRefusal as a2, linkOrganizationMalformedMessage as a3, linkOrganizationNotAMemberMessage as a4, linkOrganizationOfferMessage as a5, linkOrganizationSwitchAnnouncement as a6, memoryHeldOrganization as a7, oldestMembership as a8, orderOrganizations as a9, organizationMatches as aa, readAccountOrganizationChoices as ab, readLinkOrganizationParam as ac, readMemberships as ad, readOrganizationFavourites as ae, resolveActiveOrganization as af, resolveActiveOrganizationLazily as ag, resolveAdminSeat as ah, resolveChildOrganizationId as ai, resolveOrganizationWithLink as aj, setOrganizationFavourite as ak, storageHeldOrganization as al, toAccountOrganizationChoices as am, writeLastActiveOrganization as an, writeStartupOrganization as ao, getSession as b, signInWithOAuth as c, signInWithPassword as d, signOut as e, userCredentials as f, getPerson as g, type AccountOrganizationChoices as h, invalidatePerson as i, type ActiveOrganization as j, type ActiveOrganizationSnapshot as k, type ActiveOrganizationStatus as l, type AdminSeat as m, type AdminSeatInput as n, onSessionChange as o, type ArchiveFilter as p, type CreateActiveOrganizationOptions as q, refreshSession as r, sessionCredentials as s, type LadderInput as t, updatePerson as u, type LinkOrganizationDecision as v, type LinkOrganizationDecisionInput as w, type LinkOrganizationMembership as x, type LinkOrganizationMessages as y, type LinkOrganizationParam as z };
622
+ export { linkOrganizationMalformedMessage as $, type AuthClient as A, ORGANIZATION_ENTITY_TYPE as B, type CachedActiveOrganization as C, ORGANIZATION_RESOLUTION_TIMEOUT_MS as D, type OrganizationBootstrapGate as E, type OrganizationLapse as F, type OrganizationMembership as G, type HeldOrganizationStore as H, type OrganizationRefusal as I, type OrganizationRung as J, type ResolveWithLinkInput as K, LINK_ORGANIZATION_QUERY_KEY as L, type ResolvedOrganization as M, NOT_A_MEMBER_RECHECK_GAP_MS as N, type OrganizationsDb as O, type ParentOrganization as P, type ResolvedWithLink as Q, type ReadMembershipsOptions as R, SignInError as S, adminSeatReplacesUserContext as T, classifyLinkOrganizationValue as U, classifyOrganizationRefusal as V, createActiveOrganization as W, createNotAMemberRefusalNotice as X, createOrganizationBootstrapGate as Y, decideLinkOrganization as Z, isNotAMemberRefusal as _, getSession as a, linkOrganizationNotAMemberMessage as a0, linkOrganizationOfferMessage as a1, linkOrganizationSwitchAnnouncement as a2, memoryHeldOrganization as a3, oldestMembership as a4, orderOrganizations as a5, organizationMatches as a6, readAccountOrganizationChoices as a7, readLinkOrganizationParam as a8, readMemberships as a9, readOrganizationFavourites as aa, resolveActiveOrganization as ab, resolveActiveOrganizationLazily as ac, resolveAdminSeat as ad, resolveChildOrganizationId as ae, resolveOrganizationWithLink as af, setOrganizationFavourite as ag, storageHeldOrganization as ah, toAccountOrganizationChoices as ai, writeLastActiveOrganization as aj, writeStartupOrganization as ak, signInWithPassword as b, signOut as c, type AccountOrganizationChoices as d, type ActiveOrganization as e, type ActiveOrganizationSnapshot as f, getPerson as g, type ActiveOrganizationStatus as h, invalidatePerson as i, type AdminSeat as j, type AdminSeatInput as k, type ArchiveFilter as l, type CreateActiveOrganizationOptions as m, type LadderInput as n, onSessionChange as o, type LinkOrganizationDecision as p, type LinkOrganizationDecisionInput as q, refreshSession as r, signInWithOAuth as s, type LinkOrganizationMembership as t, updatePerson as u, type LinkOrganizationMessages as v, type LinkOrganizationParam as w, NoActiveOrganizationError as x, NotAMemberError as y, type NotAMemberRefusalNotice as z };
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/claims.ts
21
+ var claims_exports = {};
22
+ __export(claims_exports, {
23
+ PROJECT_SIGNING_KEYS: () => PROJECT_SIGNING_KEYS,
24
+ PROJECT_SIGNING_KEY_AUTHORITIES: () => PROJECT_SIGNING_KEY_AUTHORITIES,
25
+ accountFlagsFor: () => accountFlagsFor,
26
+ confirmUnverifiableSession: () => confirmUnverifiableSession,
27
+ createClaimsCache: () => createClaimsCache,
28
+ getClaimsUser: () => getClaimsUser,
29
+ isAuthTransportFailure: () => isAuthTransportFailure,
30
+ isSignedOutError: () => isSignedOutError,
31
+ isUnverifiableTokenError: () => isUnverifiableTokenError,
32
+ isUnverifiableTokenRefusal: () => isUnverifiableTokenRefusal,
33
+ looksLikeJwt: () => looksLikeJwt,
34
+ pinnedSigningKeysFor: () => pinnedSigningKeysFor,
35
+ profileFromClaims: () => profileFromClaims,
36
+ userFromClaims: () => userFromClaims
37
+ });
38
+ module.exports = __toCommonJS(claims_exports);
39
+ var import_supabase_js = require("@supabase/supabase-js");
40
+ async function getClaimsUser(client, jwt, options) {
41
+ const { data, error } = options ? await client.auth.getClaims(jwt, options) : await client.auth.getClaims(jwt);
42
+ if (error) {
43
+ if (isSignedOutError(error)) return { data: { user: null }, error: null };
44
+ return { data: { user: null }, error };
45
+ }
46
+ if (!data?.claims) return { data: { user: null }, error: null };
47
+ const user = userFromClaims(data.claims);
48
+ if (!user) {
49
+ return {
50
+ data: { user: null },
51
+ error: new import_supabase_js.AuthError("Verified token carries no `sub` claim", 401, "bad_jwt")
52
+ };
53
+ }
54
+ return { data: { user }, error: null };
55
+ }
56
+ var BUDGET_EXHAUSTED_STATUS = 408;
57
+ var BUDGET_EXHAUSTED_CODE = "auth_budget_exhausted";
58
+ function isAuthTransportFailure(error) {
59
+ if (!error || typeof error !== "object") return false;
60
+ const name = String(error.name ?? "");
61
+ if (name === "AuthRetryableFetchError" || name === "TimeoutError" || name === "AbortError") return true;
62
+ const status = error.status;
63
+ if (status === 0 || status === 504 || status === 503) return true;
64
+ return status === BUDGET_EXHAUSTED_STATUS || error.code === BUDGET_EXHAUSTED_CODE;
65
+ }
66
+ function isSignedOutError(error) {
67
+ return error instanceof import_supabase_js.AuthSessionMissingError || error.name === "AuthSessionMissingError" || error.code === "session_not_found";
68
+ }
69
+ function userFromClaims(claims) {
70
+ if (!claims || typeof claims.sub !== "string") return null;
71
+ return {
72
+ ...claims,
73
+ id: claims.sub,
74
+ app_metadata: claims.app_metadata ?? {},
75
+ user_metadata: claims.user_metadata ?? {}
76
+ };
77
+ }
78
+ function looksLikeJwt(token) {
79
+ const parts = token.split(".");
80
+ if (parts.length !== 3) return false;
81
+ try {
82
+ for (const part of parts.slice(0, 2)) {
83
+ const normalized = part.replace(/-/g, "+").replace(/_/g, "/");
84
+ const binary = atob(normalized.padEnd(Math.ceil(normalized.length / 4) * 4, "="));
85
+ const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
86
+ JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
87
+ }
88
+ return true;
89
+ } catch {
90
+ return false;
91
+ }
92
+ }
93
+ function profileFromClaims(claims) {
94
+ if (!claims) return null;
95
+ const text = (value) => typeof value === "string" && value.length > 0 ? value : null;
96
+ const id = text(claims["sub"]);
97
+ if (!id) return null;
98
+ const raw = claims["user_metadata"];
99
+ const meta = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
100
+ return {
101
+ id,
102
+ email: text(claims["email"]),
103
+ full_name: (typeof meta["full_name"] === "string" ? meta["full_name"] : null) ?? (typeof meta["name"] === "string" ? meta["name"] : null),
104
+ avatar_url: typeof meta["avatar_url"] === "string" ? meta["avatar_url"] : null,
105
+ ...typeof meta["email_verified"] === "boolean" && { email_verified: meta["email_verified"] }
106
+ };
107
+ }
108
+ function accountFlagsFor(claims) {
109
+ if (!claims) return { isGuest: false, hasAccount: false };
110
+ const isGuest = claims.is_anonymous === true;
111
+ return { isGuest, hasAccount: !isGuest };
112
+ }
113
+ var PROJECT_SIGNING_KEY_AUTHORITIES = [
114
+ "db.matrxserver.com",
115
+ "brsgrqvjdzwihsvnfqkf.supabase.co"
116
+ ];
117
+ var PROJECT_SIGNING_KEYS = [
118
+ {
119
+ alg: "ES256",
120
+ crv: "P-256",
121
+ ext: true,
122
+ key_ops: ["verify"],
123
+ kid: "a00aed0b-202c-483a-91ff-fc74719a3bb2",
124
+ kty: "EC",
125
+ use: "sig",
126
+ x: "guqOsgjJqGVU6g_K0iIXKrzixlkeXKOqkPUQCconp6U",
127
+ y: "39zQtkzlfQuPf_MtIhYmMdxNQpIR2Pkl11AToywaslY"
128
+ }
129
+ ];
130
+ function pinnedSigningKeysFor(supabaseUrl) {
131
+ if (!supabaseUrl) return [];
132
+ let host;
133
+ try {
134
+ host = new URL(supabaseUrl).host.toLowerCase();
135
+ } catch {
136
+ return [];
137
+ }
138
+ return PROJECT_SIGNING_KEY_AUTHORITIES.includes(host) ? PROJECT_SIGNING_KEYS : [];
139
+ }
140
+ function isUnverifiableTokenRefusal(result) {
141
+ if (result.status !== 401) return false;
142
+ if (result.error?.code !== "PGRST301") return false;
143
+ return !/expired/i.test(result.error?.message ?? "");
144
+ }
145
+ function isUnverifiableTokenError(error) {
146
+ if (!error) return false;
147
+ const name = String(error.name ?? "");
148
+ if (name === "AuthRetryableFetchError" || name === "TimeoutError" || name === "AbortError") return false;
149
+ if (name === "AuthSessionMissingError" || error.code === "session_not_found") return false;
150
+ const status = error.status;
151
+ if (status === 0 || status === 408 || status === 503 || status === 504) return false;
152
+ if (/expired/i.test(error.message ?? "")) return false;
153
+ return error.code === "bad_jwt" || name === "AuthInvalidJwtError";
154
+ }
155
+ async function confirmUnverifiableSession(auth, supabaseUrl) {
156
+ try {
157
+ const { error } = await auth.getClaims(void 0, { jwks: { keys: pinnedSigningKeysFor(supabaseUrl) } });
158
+ return isUnverifiableTokenError(error);
159
+ } catch {
160
+ return false;
161
+ }
162
+ }
163
+ function createClaimsCache(client, options) {
164
+ const ttl = options.ttlMs ?? 2e3;
165
+ let cached = null;
166
+ let inflight = null;
167
+ let listening = false;
168
+ return () => {
169
+ if (!listening) {
170
+ listening = true;
171
+ client.auth.onAuthStateChange((event) => {
172
+ if (event === "SIGNED_OUT" || event === "SIGNED_IN" || event === "TOKEN_REFRESHED" || event === "USER_UPDATED") {
173
+ cached = null;
174
+ }
175
+ });
176
+ }
177
+ if (cached && cached.expiresAt > Date.now()) return Promise.resolve(cached.value);
178
+ if (inflight) return inflight;
179
+ inflight = getClaimsUser(client, void 0, { jwks: { keys: pinnedSigningKeysFor(options.supabaseUrl) } }).then((result) => {
180
+ if (isUnverifiableTokenError(result.error)) options.onUnverifiable?.();
181
+ cached = { value: result, expiresAt: Date.now() + ttl };
182
+ return result;
183
+ }).finally(() => {
184
+ inflight = null;
185
+ });
186
+ return inflight;
187
+ };
188
+ }
@@ -148,4 +148,4 @@ declare function createClaimsCache(client: ClaimsCapableClient & {
148
148
  };
149
149
  }, options: ClaimsCacheOptions): () => Promise<ClaimsResult>;
150
150
 
151
- export { type ApiClaimsUser as A, type ClaimsCapableClient as C, PROJECT_SIGNING_KEYS as P, type ClaimsCacheOptions as a, type ClaimsProfile as b, type ClaimsResult as c, PROJECT_SIGNING_KEY_AUTHORITIES as d, accountFlagsFor as e, confirmUnverifiableSession as f, createClaimsCache as g, getClaimsUser as h, isAuthTransportFailure as i, isSignedOutError as j, isUnverifiableTokenError as k, isUnverifiableTokenRefusal as l, looksLikeJwt as m, profileFromClaims as n, pinnedSigningKeysFor as p, userFromClaims as u };
151
+ export { type ApiClaimsUser, type ClaimsCacheOptions, type ClaimsCapableClient, type ClaimsProfile, type ClaimsResult, PROJECT_SIGNING_KEYS, PROJECT_SIGNING_KEY_AUTHORITIES, accountFlagsFor, confirmUnverifiableSession, createClaimsCache, getClaimsUser, isAuthTransportFailure, isSignedOutError, isUnverifiableTokenError, isUnverifiableTokenRefusal, looksLikeJwt, pinnedSigningKeysFor, profileFromClaims, userFromClaims };
@@ -148,4 +148,4 @@ declare function createClaimsCache(client: ClaimsCapableClient & {
148
148
  };
149
149
  }, options: ClaimsCacheOptions): () => Promise<ClaimsResult>;
150
150
 
151
- export { type ApiClaimsUser as A, type ClaimsCapableClient as C, PROJECT_SIGNING_KEYS as P, type ClaimsCacheOptions as a, type ClaimsProfile as b, type ClaimsResult as c, PROJECT_SIGNING_KEY_AUTHORITIES as d, accountFlagsFor as e, confirmUnverifiableSession as f, createClaimsCache as g, getClaimsUser as h, isAuthTransportFailure as i, isSignedOutError as j, isUnverifiableTokenError as k, isUnverifiableTokenRefusal as l, looksLikeJwt as m, profileFromClaims as n, pinnedSigningKeysFor as p, userFromClaims as u };
151
+ export { type ApiClaimsUser, type ClaimsCacheOptions, type ClaimsCapableClient, type ClaimsProfile, type ClaimsResult, PROJECT_SIGNING_KEYS, PROJECT_SIGNING_KEY_AUTHORITIES, accountFlagsFor, confirmUnverifiableSession, createClaimsCache, getClaimsUser, isAuthTransportFailure, isSignedOutError, isUnverifiableTokenError, isUnverifiableTokenRefusal, looksLikeJwt, pinnedSigningKeysFor, profileFromClaims, userFromClaims };
package/dist/claims.js ADDED
@@ -0,0 +1,170 @@
1
+ // src/claims.ts
2
+ import {
3
+ AuthError,
4
+ AuthSessionMissingError
5
+ } from "@supabase/supabase-js";
6
+ async function getClaimsUser(client, jwt, options) {
7
+ const { data, error } = options ? await client.auth.getClaims(jwt, options) : await client.auth.getClaims(jwt);
8
+ if (error) {
9
+ if (isSignedOutError(error)) return { data: { user: null }, error: null };
10
+ return { data: { user: null }, error };
11
+ }
12
+ if (!data?.claims) return { data: { user: null }, error: null };
13
+ const user = userFromClaims(data.claims);
14
+ if (!user) {
15
+ return {
16
+ data: { user: null },
17
+ error: new AuthError("Verified token carries no `sub` claim", 401, "bad_jwt")
18
+ };
19
+ }
20
+ return { data: { user }, error: null };
21
+ }
22
+ var BUDGET_EXHAUSTED_STATUS = 408;
23
+ var BUDGET_EXHAUSTED_CODE = "auth_budget_exhausted";
24
+ function isAuthTransportFailure(error) {
25
+ if (!error || typeof error !== "object") return false;
26
+ const name = String(error.name ?? "");
27
+ if (name === "AuthRetryableFetchError" || name === "TimeoutError" || name === "AbortError") return true;
28
+ const status = error.status;
29
+ if (status === 0 || status === 504 || status === 503) return true;
30
+ return status === BUDGET_EXHAUSTED_STATUS || error.code === BUDGET_EXHAUSTED_CODE;
31
+ }
32
+ function isSignedOutError(error) {
33
+ return error instanceof AuthSessionMissingError || error.name === "AuthSessionMissingError" || error.code === "session_not_found";
34
+ }
35
+ function userFromClaims(claims) {
36
+ if (!claims || typeof claims.sub !== "string") return null;
37
+ return {
38
+ ...claims,
39
+ id: claims.sub,
40
+ app_metadata: claims.app_metadata ?? {},
41
+ user_metadata: claims.user_metadata ?? {}
42
+ };
43
+ }
44
+ function looksLikeJwt(token) {
45
+ const parts = token.split(".");
46
+ if (parts.length !== 3) return false;
47
+ try {
48
+ for (const part of parts.slice(0, 2)) {
49
+ const normalized = part.replace(/-/g, "+").replace(/_/g, "/");
50
+ const binary = atob(normalized.padEnd(Math.ceil(normalized.length / 4) * 4, "="));
51
+ const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
52
+ JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
53
+ }
54
+ return true;
55
+ } catch {
56
+ return false;
57
+ }
58
+ }
59
+ function profileFromClaims(claims) {
60
+ if (!claims) return null;
61
+ const text = (value) => typeof value === "string" && value.length > 0 ? value : null;
62
+ const id = text(claims["sub"]);
63
+ if (!id) return null;
64
+ const raw = claims["user_metadata"];
65
+ const meta = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
66
+ return {
67
+ id,
68
+ email: text(claims["email"]),
69
+ full_name: (typeof meta["full_name"] === "string" ? meta["full_name"] : null) ?? (typeof meta["name"] === "string" ? meta["name"] : null),
70
+ avatar_url: typeof meta["avatar_url"] === "string" ? meta["avatar_url"] : null,
71
+ ...typeof meta["email_verified"] === "boolean" && { email_verified: meta["email_verified"] }
72
+ };
73
+ }
74
+ function accountFlagsFor(claims) {
75
+ if (!claims) return { isGuest: false, hasAccount: false };
76
+ const isGuest = claims.is_anonymous === true;
77
+ return { isGuest, hasAccount: !isGuest };
78
+ }
79
+ var PROJECT_SIGNING_KEY_AUTHORITIES = [
80
+ "db.matrxserver.com",
81
+ "brsgrqvjdzwihsvnfqkf.supabase.co"
82
+ ];
83
+ var PROJECT_SIGNING_KEYS = [
84
+ {
85
+ alg: "ES256",
86
+ crv: "P-256",
87
+ ext: true,
88
+ key_ops: ["verify"],
89
+ kid: "a00aed0b-202c-483a-91ff-fc74719a3bb2",
90
+ kty: "EC",
91
+ use: "sig",
92
+ x: "guqOsgjJqGVU6g_K0iIXKrzixlkeXKOqkPUQCconp6U",
93
+ y: "39zQtkzlfQuPf_MtIhYmMdxNQpIR2Pkl11AToywaslY"
94
+ }
95
+ ];
96
+ function pinnedSigningKeysFor(supabaseUrl) {
97
+ if (!supabaseUrl) return [];
98
+ let host;
99
+ try {
100
+ host = new URL(supabaseUrl).host.toLowerCase();
101
+ } catch {
102
+ return [];
103
+ }
104
+ return PROJECT_SIGNING_KEY_AUTHORITIES.includes(host) ? PROJECT_SIGNING_KEYS : [];
105
+ }
106
+ function isUnverifiableTokenRefusal(result) {
107
+ if (result.status !== 401) return false;
108
+ if (result.error?.code !== "PGRST301") return false;
109
+ return !/expired/i.test(result.error?.message ?? "");
110
+ }
111
+ function isUnverifiableTokenError(error) {
112
+ if (!error) return false;
113
+ const name = String(error.name ?? "");
114
+ if (name === "AuthRetryableFetchError" || name === "TimeoutError" || name === "AbortError") return false;
115
+ if (name === "AuthSessionMissingError" || error.code === "session_not_found") return false;
116
+ const status = error.status;
117
+ if (status === 0 || status === 408 || status === 503 || status === 504) return false;
118
+ if (/expired/i.test(error.message ?? "")) return false;
119
+ return error.code === "bad_jwt" || name === "AuthInvalidJwtError";
120
+ }
121
+ async function confirmUnverifiableSession(auth, supabaseUrl) {
122
+ try {
123
+ const { error } = await auth.getClaims(void 0, { jwks: { keys: pinnedSigningKeysFor(supabaseUrl) } });
124
+ return isUnverifiableTokenError(error);
125
+ } catch {
126
+ return false;
127
+ }
128
+ }
129
+ function createClaimsCache(client, options) {
130
+ const ttl = options.ttlMs ?? 2e3;
131
+ let cached = null;
132
+ let inflight = null;
133
+ let listening = false;
134
+ return () => {
135
+ if (!listening) {
136
+ listening = true;
137
+ client.auth.onAuthStateChange((event) => {
138
+ if (event === "SIGNED_OUT" || event === "SIGNED_IN" || event === "TOKEN_REFRESHED" || event === "USER_UPDATED") {
139
+ cached = null;
140
+ }
141
+ });
142
+ }
143
+ if (cached && cached.expiresAt > Date.now()) return Promise.resolve(cached.value);
144
+ if (inflight) return inflight;
145
+ inflight = getClaimsUser(client, void 0, { jwks: { keys: pinnedSigningKeysFor(options.supabaseUrl) } }).then((result) => {
146
+ if (isUnverifiableTokenError(result.error)) options.onUnverifiable?.();
147
+ cached = { value: result, expiresAt: Date.now() + ttl };
148
+ return result;
149
+ }).finally(() => {
150
+ inflight = null;
151
+ });
152
+ return inflight;
153
+ };
154
+ }
155
+ export {
156
+ PROJECT_SIGNING_KEYS,
157
+ PROJECT_SIGNING_KEY_AUTHORITIES,
158
+ accountFlagsFor,
159
+ confirmUnverifiableSession,
160
+ createClaimsCache,
161
+ getClaimsUser,
162
+ isAuthTransportFailure,
163
+ isSignedOutError,
164
+ isUnverifiableTokenError,
165
+ isUnverifiableTokenRefusal,
166
+ looksLikeJwt,
167
+ pinnedSigningKeysFor,
168
+ profileFromClaims,
169
+ userFromClaims
170
+ };
@@ -23,9 +23,31 @@ __export(credentials_exports, {
23
23
  API_KEY_PREFIX: () => API_KEY_PREFIX,
24
24
  MATRX_HEADERS: () => MATRX_HEADERS,
25
25
  credentialToHeaders: () => credentialToHeaders,
26
- toCredentialsPort: () => toCredentialsPort
26
+ sessionCredentials: () => sessionCredentials,
27
+ toCredentialsPort: () => toCredentialsPort,
28
+ userCredentials: () => userCredentials
27
29
  });
28
30
  module.exports = __toCommonJS(credentials_exports);
31
+
32
+ // src/session-credentials.ts
33
+ function sessionCredentials(client) {
34
+ return {
35
+ async get() {
36
+ if (!client.auth) return null;
37
+ const { data } = await client.auth.getSession();
38
+ return data.session ? { kind: "user", accessToken: data.session.access_token } : null;
39
+ },
40
+ onChange(cb) {
41
+ if (!client.auth) return () => {
42
+ };
43
+ const { data } = client.auth.onAuthStateChange(() => cb());
44
+ return () => data.subscription.unsubscribe();
45
+ }
46
+ };
47
+ }
48
+ var userCredentials = sessionCredentials;
49
+
50
+ // src/credentials.ts
29
51
  var MATRX_HEADERS = {
30
52
  authorization: "Authorization",
31
53
  fingerprint: "X-Fingerprint-ID",
@@ -1,3 +1,39 @@
1
+ /** The slice of a client the session credential reads: its `auth`, when it has one. */
2
+ interface SessionSourceLike {
3
+ auth?: {
4
+ getSession(): PromiseLike<{
5
+ data: {
6
+ session: {
7
+ access_token: string;
8
+ } | null;
9
+ };
10
+ }>;
11
+ onAuthStateChange(cb: (event: string, session: unknown) => void): {
12
+ data: {
13
+ subscription: {
14
+ unsubscribe(): void;
15
+ };
16
+ };
17
+ };
18
+ } | undefined;
19
+ }
20
+ /** The `user` credential port (structural; the shape `@ai-matrx/api`'s `CredentialsPort` takes). */
21
+ interface UserCredentialsPort {
22
+ get(): Promise<{
23
+ kind: "user";
24
+ accessToken: string;
25
+ } | null>;
26
+ onChange?(cb: () => void): () => void;
27
+ }
28
+ /**
29
+ * THE ONE session → credential mapping: the current access token as api's `user` credential,
30
+ * re-read on every call (a refresh rotates it), with `onChange` on every session change.
31
+ * A client with no `auth` is anonymous (null), never an error.
32
+ */
33
+ declare function sessionCredentials(client: SessionSourceLike): UserCredentialsPort;
34
+ /** The session as `@ai-matrx/api`'s `user` credential — the name `@ai-matrx/data/auth` shipped. */
35
+ declare const userCredentials: typeof sessionCredentials;
36
+
1
37
  /**
2
38
  * The credentials port — the ONE credential→header mapping for every client
3
39
  * of every AI Matrx server (package lines v3 §3.4; API-key lane C16).
@@ -86,4 +122,4 @@ type CredentialsSetting = MatrxCredential | null | (() => MatrxCredential | null
86
122
  /** Normalize the ONE credentials setting into a `CredentialsPort`. */
87
123
  declare function toCredentialsPort(setting: CredentialsSetting | undefined): CredentialsPort;
88
124
 
89
- export { API_KEY_PREFIX, type CredentialsPort, type CredentialsSetting, MATRX_HEADERS, type MatrxCredential, type MatrxCredentialKind, credentialToHeaders, toCredentialsPort };
125
+ export { API_KEY_PREFIX, type CredentialsPort, type CredentialsSetting, MATRX_HEADERS, type MatrxCredential, type MatrxCredentialKind, type SessionSourceLike, type UserCredentialsPort, credentialToHeaders, sessionCredentials, toCredentialsPort, userCredentials };
@@ -1,3 +1,39 @@
1
+ /** The slice of a client the session credential reads: its `auth`, when it has one. */
2
+ interface SessionSourceLike {
3
+ auth?: {
4
+ getSession(): PromiseLike<{
5
+ data: {
6
+ session: {
7
+ access_token: string;
8
+ } | null;
9
+ };
10
+ }>;
11
+ onAuthStateChange(cb: (event: string, session: unknown) => void): {
12
+ data: {
13
+ subscription: {
14
+ unsubscribe(): void;
15
+ };
16
+ };
17
+ };
18
+ } | undefined;
19
+ }
20
+ /** The `user` credential port (structural; the shape `@ai-matrx/api`'s `CredentialsPort` takes). */
21
+ interface UserCredentialsPort {
22
+ get(): Promise<{
23
+ kind: "user";
24
+ accessToken: string;
25
+ } | null>;
26
+ onChange?(cb: () => void): () => void;
27
+ }
28
+ /**
29
+ * THE ONE session → credential mapping: the current access token as api's `user` credential,
30
+ * re-read on every call (a refresh rotates it), with `onChange` on every session change.
31
+ * A client with no `auth` is anonymous (null), never an error.
32
+ */
33
+ declare function sessionCredentials(client: SessionSourceLike): UserCredentialsPort;
34
+ /** The session as `@ai-matrx/api`'s `user` credential — the name `@ai-matrx/data/auth` shipped. */
35
+ declare const userCredentials: typeof sessionCredentials;
36
+
1
37
  /**
2
38
  * The credentials port — the ONE credential→header mapping for every client
3
39
  * of every AI Matrx server (package lines v3 §3.4; API-key lane C16).
@@ -86,4 +122,4 @@ type CredentialsSetting = MatrxCredential | null | (() => MatrxCredential | null
86
122
  /** Normalize the ONE credentials setting into a `CredentialsPort`. */
87
123
  declare function toCredentialsPort(setting: CredentialsSetting | undefined): CredentialsPort;
88
124
 
89
- export { API_KEY_PREFIX, type CredentialsPort, type CredentialsSetting, MATRX_HEADERS, type MatrxCredential, type MatrxCredentialKind, credentialToHeaders, toCredentialsPort };
125
+ export { API_KEY_PREFIX, type CredentialsPort, type CredentialsSetting, MATRX_HEADERS, type MatrxCredential, type MatrxCredentialKind, type SessionSourceLike, type UserCredentialsPort, credentialToHeaders, sessionCredentials, toCredentialsPort, userCredentials };
@@ -1,3 +1,21 @@
1
+ // src/session-credentials.ts
2
+ function sessionCredentials(client) {
3
+ return {
4
+ async get() {
5
+ if (!client.auth) return null;
6
+ const { data } = await client.auth.getSession();
7
+ return data.session ? { kind: "user", accessToken: data.session.access_token } : null;
8
+ },
9
+ onChange(cb) {
10
+ if (!client.auth) return () => {
11
+ };
12
+ const { data } = client.auth.onAuthStateChange(() => cb());
13
+ return () => data.subscription.unsubscribe();
14
+ }
15
+ };
16
+ }
17
+ var userCredentials = sessionCredentials;
18
+
1
19
  // src/credentials.ts
2
20
  var MATRX_HEADERS = {
3
21
  authorization: "Authorization",
@@ -43,5 +61,7 @@ export {
43
61
  API_KEY_PREFIX,
44
62
  MATRX_HEADERS,
45
63
  credentialToHeaders,
46
- toCredentialsPort
64
+ sessionCredentials,
65
+ toCredentialsPort,
66
+ userCredentials
47
67
  };
package/dist/index.cjs CHANGED
@@ -64,6 +64,24 @@ __export(src_exports, {
64
64
  });
65
65
  module.exports = __toCommonJS(src_exports);
66
66
 
67
+ // src/session-credentials.ts
68
+ function sessionCredentials(client) {
69
+ return {
70
+ async get() {
71
+ if (!client.auth) return null;
72
+ const { data } = await client.auth.getSession();
73
+ return data.session ? { kind: "user", accessToken: data.session.access_token } : null;
74
+ },
75
+ onChange(cb) {
76
+ if (!client.auth) return () => {
77
+ };
78
+ const { data } = client.auth.onAuthStateChange(() => cb());
79
+ return () => data.subscription.unsubscribe();
80
+ }
81
+ };
82
+ }
83
+ var userCredentials = sessionCredentials;
84
+
67
85
  // src/claims.ts
68
86
  var import_supabase_js = require("@supabase/supabase-js");
69
87
  async function getClaimsUser(client, jwt, options) {
@@ -543,22 +561,6 @@ async function updatePerson(client, attributes) {
543
561
  invalidatePerson(client);
544
562
  return check("updatePerson", data, error).user;
545
563
  }
546
- function sessionCredentials(client) {
547
- return {
548
- async get() {
549
- if (!client.auth) return null;
550
- const { data } = await client.auth.getSession();
551
- return data.session ? { kind: "user", accessToken: data.session.access_token } : null;
552
- },
553
- onChange(cb) {
554
- if (!client.auth) return () => {
555
- };
556
- const { data } = client.auth.onAuthStateChange(() => cb());
557
- return () => data.subscription.unsubscribe();
558
- }
559
- };
560
- }
561
- var userCredentials = sessionCredentials;
562
564
  async function refreshSession(client) {
563
565
  const { data, error } = await client.auth.refreshSession();
564
566
  const ok = check("refreshSession", data, error);
package/dist/index.d.cts CHANGED
@@ -1,11 +1,11 @@
1
- import { H as HeldOrganizationStore, A as AuthClient } from './active-organization-B6s9ONIe.cjs';
2
- export { S as SessionSourceLike, a as SignInError, U as UserCredentialsPort, g as getPerson, b as getSession, i as invalidatePerson, o as onSessionChange, r as refreshSession, s as sessionCredentials, c as signInWithOAuth, d as signInWithPassword, e as signOut, u as updatePerson, f as userCredentials } from './active-organization-B6s9ONIe.cjs';
1
+ import { H as HeldOrganizationStore, A as AuthClient } from './active-organization-Djm9QJt8.cjs';
2
+ export { S as SignInError, g as getPerson, a as getSession, i as invalidatePerson, o as onSessionChange, r as refreshSession, s as signInWithOAuth, b as signInWithPassword, c as signOut, u as updatePerson } from './active-organization-Djm9QJt8.cjs';
3
3
  import { S as SessionStorage, M as MatrxOAuthClient } from './matrx-oauth-_Ji8X5Wm.cjs';
4
4
  export { C as ChromeStorageAreaLike, a as StorageUnavailableError, b as browserStorage, e as extensionStorage, k as keyValueStorage, m as memoryStorage } from './matrx-oauth-_Ji8X5Wm.cjs';
5
5
  import { SupabaseClient, User } from '@supabase/supabase-js';
6
6
  export { AuthChangeEvent, Session, User, UserAttributes } from '@supabase/supabase-js';
7
- export { CredentialsPort, MatrxCredential, MatrxCredentialKind } from './credentials.cjs';
8
- export { A as ApiClaimsUser, a as ClaimsCacheOptions, C as ClaimsCapableClient, b as ClaimsProfile, c as ClaimsResult, P as PROJECT_SIGNING_KEYS, d as PROJECT_SIGNING_KEY_AUTHORITIES, e as accountFlagsFor, f as confirmUnverifiableSession, g as createClaimsCache, h as getClaimsUser, i as isAuthTransportFailure, j as isSignedOutError, k as isUnverifiableTokenError, l as isUnverifiableTokenRefusal, m as looksLikeJwt, p as pinnedSigningKeysFor, n as profileFromClaims, u as userFromClaims } from './claims-Vno769TE.cjs';
7
+ export { CredentialsPort, MatrxCredential, MatrxCredentialKind, SessionSourceLike, UserCredentialsPort, sessionCredentials, userCredentials } from './credentials.cjs';
8
+ export { ApiClaimsUser, ClaimsCacheOptions, ClaimsCapableClient, ClaimsProfile, ClaimsResult, PROJECT_SIGNING_KEYS, PROJECT_SIGNING_KEY_AUTHORITIES, accountFlagsFor, confirmUnverifiableSession, createClaimsCache, getClaimsUser, isAuthTransportFailure, isSignedOutError, isUnverifiableTokenError, isUnverifiableTokenRefusal, looksLikeJwt, pinnedSigningKeysFor, profileFromClaims, userFromClaims } from './claims.cjs';
9
9
 
10
10
  /** How long a request may wait for the first auth report before going anyway. */
11
11
  declare const SESSION_ATTACH_BUDGET_MS = 3000;
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { H as HeldOrganizationStore, A as AuthClient } from './active-organization-B6s9ONIe.js';
2
- export { S as SessionSourceLike, a as SignInError, U as UserCredentialsPort, g as getPerson, b as getSession, i as invalidatePerson, o as onSessionChange, r as refreshSession, s as sessionCredentials, c as signInWithOAuth, d as signInWithPassword, e as signOut, u as updatePerson, f as userCredentials } from './active-organization-B6s9ONIe.js';
1
+ import { H as HeldOrganizationStore, A as AuthClient } from './active-organization-Djm9QJt8.js';
2
+ export { S as SignInError, g as getPerson, a as getSession, i as invalidatePerson, o as onSessionChange, r as refreshSession, s as signInWithOAuth, b as signInWithPassword, c as signOut, u as updatePerson } from './active-organization-Djm9QJt8.js';
3
3
  import { S as SessionStorage, M as MatrxOAuthClient } from './matrx-oauth-_Ji8X5Wm.js';
4
4
  export { C as ChromeStorageAreaLike, a as StorageUnavailableError, b as browserStorage, e as extensionStorage, k as keyValueStorage, m as memoryStorage } from './matrx-oauth-_Ji8X5Wm.js';
5
5
  import { SupabaseClient, User } from '@supabase/supabase-js';
6
6
  export { AuthChangeEvent, Session, User, UserAttributes } from '@supabase/supabase-js';
7
- export { CredentialsPort, MatrxCredential, MatrxCredentialKind } from './credentials.js';
8
- export { A as ApiClaimsUser, a as ClaimsCacheOptions, C as ClaimsCapableClient, b as ClaimsProfile, c as ClaimsResult, P as PROJECT_SIGNING_KEYS, d as PROJECT_SIGNING_KEY_AUTHORITIES, e as accountFlagsFor, f as confirmUnverifiableSession, g as createClaimsCache, h as getClaimsUser, i as isAuthTransportFailure, j as isSignedOutError, k as isUnverifiableTokenError, l as isUnverifiableTokenRefusal, m as looksLikeJwt, p as pinnedSigningKeysFor, n as profileFromClaims, u as userFromClaims } from './claims-Vno769TE.js';
7
+ export { CredentialsPort, MatrxCredential, MatrxCredentialKind, SessionSourceLike, UserCredentialsPort, sessionCredentials, userCredentials } from './credentials.js';
8
+ export { ApiClaimsUser, ClaimsCacheOptions, ClaimsCapableClient, ClaimsProfile, ClaimsResult, PROJECT_SIGNING_KEYS, PROJECT_SIGNING_KEY_AUTHORITIES, accountFlagsFor, confirmUnverifiableSession, createClaimsCache, getClaimsUser, isAuthTransportFailure, isSignedOutError, isUnverifiableTokenError, isUnverifiableTokenRefusal, looksLikeJwt, pinnedSigningKeysFor, profileFromClaims, userFromClaims } from './claims.js';
9
9
 
10
10
  /** How long a request may wait for the first auth report before going anyway. */
11
11
  declare const SESSION_ATTACH_BUDGET_MS = 3000;
package/dist/index.js CHANGED
@@ -1,3 +1,21 @@
1
+ // src/session-credentials.ts
2
+ function sessionCredentials(client) {
3
+ return {
4
+ async get() {
5
+ if (!client.auth) return null;
6
+ const { data } = await client.auth.getSession();
7
+ return data.session ? { kind: "user", accessToken: data.session.access_token } : null;
8
+ },
9
+ onChange(cb) {
10
+ if (!client.auth) return () => {
11
+ };
12
+ const { data } = client.auth.onAuthStateChange(() => cb());
13
+ return () => data.subscription.unsubscribe();
14
+ }
15
+ };
16
+ }
17
+ var userCredentials = sessionCredentials;
18
+
1
19
  // src/claims.ts
2
20
  import {
3
21
  AuthError,
@@ -480,22 +498,6 @@ async function updatePerson(client, attributes) {
480
498
  invalidatePerson(client);
481
499
  return check("updatePerson", data, error).user;
482
500
  }
483
- function sessionCredentials(client) {
484
- return {
485
- async get() {
486
- if (!client.auth) return null;
487
- const { data } = await client.auth.getSession();
488
- return data.session ? { kind: "user", accessToken: data.session.access_token } : null;
489
- },
490
- onChange(cb) {
491
- if (!client.auth) return () => {
492
- };
493
- const { data } = client.auth.onAuthStateChange(() => cb());
494
- return () => data.subscription.unsubscribe();
495
- }
496
- };
497
- }
498
- var userCredentials = sessionCredentials;
499
501
  async function refreshSession(client) {
500
502
  const { data, error } = await client.auth.refreshSession();
501
503
  const ok = check("refreshSession", data, error);
package/dist/next.d.cts CHANGED
@@ -3,7 +3,7 @@ import { DatabaseLike, NextBrowserClient } from './browser.cjs';
3
3
  import { b as AuthCookieValue, A as AuthCookie, a as AuthCookieOptions } from './auth-cookie-QPVLJJwP.cjs';
4
4
  export { C as CreateAuthCookieArgs, M as MATRX_AUTH_COOKIE, c as createAuthCookie } from './auth-cookie-QPVLJJwP.cjs';
5
5
  import { SupabaseClient } from '@supabase/supabase-js';
6
- import { C as ClaimsCapableClient, A as ApiClaimsUser } from './claims-Vno769TE.cjs';
6
+ import { ClaimsCapableClient, ApiClaimsUser } from './claims.cjs';
7
7
 
8
8
  /**
9
9
  * @ai-matrx/data/next — the Next.js Supabase binding.
package/dist/next.d.ts CHANGED
@@ -3,7 +3,7 @@ import { DatabaseLike, NextBrowserClient } from './browser.js';
3
3
  import { b as AuthCookieValue, A as AuthCookie, a as AuthCookieOptions } from './auth-cookie-QPVLJJwP.js';
4
4
  export { C as CreateAuthCookieArgs, M as MATRX_AUTH_COOKIE, c as createAuthCookie } from './auth-cookie-QPVLJJwP.js';
5
5
  import { SupabaseClient } from '@supabase/supabase-js';
6
- import { C as ClaimsCapableClient, A as ApiClaimsUser } from './claims-Vno769TE.js';
6
+ import { ClaimsCapableClient, ApiClaimsUser } from './claims.js';
7
7
 
8
8
  /**
9
9
  * @ai-matrx/data/next — the Next.js Supabase binding.
@@ -1,5 +1,5 @@
1
- import { O as OrganizationsDb } from './active-organization-B6s9ONIe.cjs';
2
- export { h as AccountOrganizationChoices, j as ActiveOrganization, k as ActiveOrganizationSnapshot, l as ActiveOrganizationStatus, m as AdminSeat, n as AdminSeatInput, p as ArchiveFilter, C as CachedActiveOrganization, q as CreateActiveOrganizationOptions, H as HeldOrganizationStore, L as LINK_ORGANIZATION_QUERY_KEY, t as LadderInput, v as LinkOrganizationDecision, w as LinkOrganizationDecisionInput, x as LinkOrganizationMembership, y as LinkOrganizationMessages, z as LinkOrganizationParam, N as NOT_A_MEMBER_RECHECK_GAP_MS, B as NoActiveOrganizationError, D as NotAMemberError, E as NotAMemberRefusalNotice, F as ORGANIZATION_ENTITY_TYPE, G as ORGANIZATION_RESOLUTION_TIMEOUT_MS, I as OrganizationBootstrapGate, J as OrganizationLapse, K as OrganizationMembership, M as OrganizationRefusal, P as OrganizationRung, Q as ParentOrganization, R as ReadMembershipsOptions, T as ResolveWithLinkInput, V as ResolvedOrganization, W as ResolvedWithLink, X as adminSeatReplacesUserContext, Y as classifyLinkOrganizationValue, Z as classifyOrganizationRefusal, _ as createActiveOrganization, $ as createNotAMemberRefusalNotice, a0 as createOrganizationBootstrapGate, a1 as decideLinkOrganization, a2 as isNotAMemberRefusal, a3 as linkOrganizationMalformedMessage, a4 as linkOrganizationNotAMemberMessage, a5 as linkOrganizationOfferMessage, a6 as linkOrganizationSwitchAnnouncement, a7 as memoryHeldOrganization, a8 as oldestMembership, a9 as orderOrganizations, aa as organizationMatches, ab as readAccountOrganizationChoices, ac as readLinkOrganizationParam, ad as readMemberships, ae as readOrganizationFavourites, af as resolveActiveOrganization, ag as resolveActiveOrganizationLazily, ah as resolveAdminSeat, ai as resolveChildOrganizationId, aj as resolveOrganizationWithLink, ak as setOrganizationFavourite, al as storageHeldOrganization, am as toAccountOrganizationChoices, an as writeLastActiveOrganization, ao as writeStartupOrganization } from './active-organization-B6s9ONIe.cjs';
1
+ import { O as OrganizationsDb } from './active-organization-Djm9QJt8.cjs';
2
+ export { d as AccountOrganizationChoices, e as ActiveOrganization, f as ActiveOrganizationSnapshot, h as ActiveOrganizationStatus, j as AdminSeat, k as AdminSeatInput, l as ArchiveFilter, C as CachedActiveOrganization, m as CreateActiveOrganizationOptions, H as HeldOrganizationStore, L as LINK_ORGANIZATION_QUERY_KEY, n as LadderInput, p as LinkOrganizationDecision, q as LinkOrganizationDecisionInput, t as LinkOrganizationMembership, v as LinkOrganizationMessages, w as LinkOrganizationParam, N as NOT_A_MEMBER_RECHECK_GAP_MS, x as NoActiveOrganizationError, y as NotAMemberError, z as NotAMemberRefusalNotice, B as ORGANIZATION_ENTITY_TYPE, D as ORGANIZATION_RESOLUTION_TIMEOUT_MS, E as OrganizationBootstrapGate, F as OrganizationLapse, G as OrganizationMembership, I as OrganizationRefusal, J as OrganizationRung, P as ParentOrganization, R as ReadMembershipsOptions, K as ResolveWithLinkInput, M as ResolvedOrganization, Q as ResolvedWithLink, T as adminSeatReplacesUserContext, U as classifyLinkOrganizationValue, V as classifyOrganizationRefusal, W as createActiveOrganization, X as createNotAMemberRefusalNotice, Y as createOrganizationBootstrapGate, Z as decideLinkOrganization, _ as isNotAMemberRefusal, $ as linkOrganizationMalformedMessage, a0 as linkOrganizationNotAMemberMessage, a1 as linkOrganizationOfferMessage, a2 as linkOrganizationSwitchAnnouncement, a3 as memoryHeldOrganization, a4 as oldestMembership, a5 as orderOrganizations, a6 as organizationMatches, a7 as readAccountOrganizationChoices, a8 as readLinkOrganizationParam, a9 as readMemberships, aa as readOrganizationFavourites, ab as resolveActiveOrganization, ac as resolveActiveOrganizationLazily, ad as resolveAdminSeat, ae as resolveChildOrganizationId, af as resolveOrganizationWithLink, ag as setOrganizationFavourite, ah as storageHeldOrganization, ai as toAccountOrganizationChoices, aj as writeLastActiveOrganization, ak as writeStartupOrganization } from './active-organization-Djm9QJt8.cjs';
3
3
  import '@supabase/supabase-js';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { O as OrganizationsDb } from './active-organization-B6s9ONIe.js';
2
- export { h as AccountOrganizationChoices, j as ActiveOrganization, k as ActiveOrganizationSnapshot, l as ActiveOrganizationStatus, m as AdminSeat, n as AdminSeatInput, p as ArchiveFilter, C as CachedActiveOrganization, q as CreateActiveOrganizationOptions, H as HeldOrganizationStore, L as LINK_ORGANIZATION_QUERY_KEY, t as LadderInput, v as LinkOrganizationDecision, w as LinkOrganizationDecisionInput, x as LinkOrganizationMembership, y as LinkOrganizationMessages, z as LinkOrganizationParam, N as NOT_A_MEMBER_RECHECK_GAP_MS, B as NoActiveOrganizationError, D as NotAMemberError, E as NotAMemberRefusalNotice, F as ORGANIZATION_ENTITY_TYPE, G as ORGANIZATION_RESOLUTION_TIMEOUT_MS, I as OrganizationBootstrapGate, J as OrganizationLapse, K as OrganizationMembership, M as OrganizationRefusal, P as OrganizationRung, Q as ParentOrganization, R as ReadMembershipsOptions, T as ResolveWithLinkInput, V as ResolvedOrganization, W as ResolvedWithLink, X as adminSeatReplacesUserContext, Y as classifyLinkOrganizationValue, Z as classifyOrganizationRefusal, _ as createActiveOrganization, $ as createNotAMemberRefusalNotice, a0 as createOrganizationBootstrapGate, a1 as decideLinkOrganization, a2 as isNotAMemberRefusal, a3 as linkOrganizationMalformedMessage, a4 as linkOrganizationNotAMemberMessage, a5 as linkOrganizationOfferMessage, a6 as linkOrganizationSwitchAnnouncement, a7 as memoryHeldOrganization, a8 as oldestMembership, a9 as orderOrganizations, aa as organizationMatches, ab as readAccountOrganizationChoices, ac as readLinkOrganizationParam, ad as readMemberships, ae as readOrganizationFavourites, af as resolveActiveOrganization, ag as resolveActiveOrganizationLazily, ah as resolveAdminSeat, ai as resolveChildOrganizationId, aj as resolveOrganizationWithLink, ak as setOrganizationFavourite, al as storageHeldOrganization, am as toAccountOrganizationChoices, an as writeLastActiveOrganization, ao as writeStartupOrganization } from './active-organization-B6s9ONIe.js';
1
+ import { O as OrganizationsDb } from './active-organization-Djm9QJt8.js';
2
+ export { d as AccountOrganizationChoices, e as ActiveOrganization, f as ActiveOrganizationSnapshot, h as ActiveOrganizationStatus, j as AdminSeat, k as AdminSeatInput, l as ArchiveFilter, C as CachedActiveOrganization, m as CreateActiveOrganizationOptions, H as HeldOrganizationStore, L as LINK_ORGANIZATION_QUERY_KEY, n as LadderInput, p as LinkOrganizationDecision, q as LinkOrganizationDecisionInput, t as LinkOrganizationMembership, v as LinkOrganizationMessages, w as LinkOrganizationParam, N as NOT_A_MEMBER_RECHECK_GAP_MS, x as NoActiveOrganizationError, y as NotAMemberError, z as NotAMemberRefusalNotice, B as ORGANIZATION_ENTITY_TYPE, D as ORGANIZATION_RESOLUTION_TIMEOUT_MS, E as OrganizationBootstrapGate, F as OrganizationLapse, G as OrganizationMembership, I as OrganizationRefusal, J as OrganizationRung, P as ParentOrganization, R as ReadMembershipsOptions, K as ResolveWithLinkInput, M as ResolvedOrganization, Q as ResolvedWithLink, T as adminSeatReplacesUserContext, U as classifyLinkOrganizationValue, V as classifyOrganizationRefusal, W as createActiveOrganization, X as createNotAMemberRefusalNotice, Y as createOrganizationBootstrapGate, Z as decideLinkOrganization, _ as isNotAMemberRefusal, $ as linkOrganizationMalformedMessage, a0 as linkOrganizationNotAMemberMessage, a1 as linkOrganizationOfferMessage, a2 as linkOrganizationSwitchAnnouncement, a3 as memoryHeldOrganization, a4 as oldestMembership, a5 as orderOrganizations, a6 as organizationMatches, a7 as readAccountOrganizationChoices, a8 as readLinkOrganizationParam, a9 as readMemberships, aa as readOrganizationFavourites, ab as resolveActiveOrganization, ac as resolveActiveOrganizationLazily, ad as resolveAdminSeat, ae as resolveChildOrganizationId, af as resolveOrganizationWithLink, ag as setOrganizationFavourite, ah as storageHeldOrganization, ai as toAccountOrganizationChoices, aj as writeLastActiveOrganization, ak as writeStartupOrganization } from './active-organization-Djm9QJt8.js';
3
3
  import '@supabase/supabase-js';
4
4
 
5
5
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/auth",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "description": "AI Matrx sign-in, session and organizations for every app: sign in/out, session storage and refresh per platform (browser, Next.js, extension, desktop, Node), the current person, their organizations and favourites, the one active organization (held requests, never a list filter), and the credentials @ai-matrx/data and @ai-matrx/api read.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -62,6 +62,16 @@
62
62
  "default": "./dist/credentials.cjs"
63
63
  }
64
64
  },
65
+ "./claims": {
66
+ "import": {
67
+ "types": "./dist/claims.d.ts",
68
+ "default": "./dist/claims.js"
69
+ },
70
+ "require": {
71
+ "types": "./dist/claims.d.cts",
72
+ "default": "./dist/claims.cjs"
73
+ }
74
+ },
65
75
  "./session-identity": {
66
76
  "import": {
67
77
  "types": "./dist/session-identity.d.ts",
@@ -221,5 +231,5 @@
221
231
  "test": "vitest run",
222
232
  "verify:tarball": "node ./scripts/verify-tarball.mjs"
223
233
  },
224
- "gitHead": "02e0da320427a864e9ac16d9296ba86ff08599af"
234
+ "gitHead": "b887d4308f04cff5b70036c6f94054e51598bb56"
225
235
  }