@object-ui/auth 17.5.0 → 17.6.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.
- package/CHANGELOG.md +110 -0
- package/README.md +148 -0
- package/dist/ActiveOrganizationStorage.d.ts +168 -0
- package/dist/ActiveOrganizationStorage.d.ts.map +1 -0
- package/dist/ActiveOrganizationStorage.js +515 -0
- package/dist/AuthContext.d.ts +19 -1
- package/dist/AuthContext.d.ts.map +1 -1
- package/dist/AuthGuard.d.ts +8 -1
- package/dist/AuthGuard.d.ts.map +1 -1
- package/dist/AuthGuard.js +16 -3
- package/dist/AuthProvider.d.ts +1 -1
- package/dist/AuthProvider.d.ts.map +1 -1
- package/dist/AuthProvider.js +272 -7
- package/dist/ForgotPasswordForm.d.ts +1 -1
- package/dist/ForgotPasswordForm.d.ts.map +1 -1
- package/dist/ForgotPasswordForm.js +5 -5
- package/dist/LoginForm.d.ts +1 -1
- package/dist/LoginForm.d.ts.map +1 -1
- package/dist/LoginForm.js +4 -4
- package/dist/PreviewBanner.js +1 -1
- package/dist/RegisterForm.d.ts +1 -1
- package/dist/RegisterForm.d.ts.map +1 -1
- package/dist/RegisterForm.js +3 -3
- package/dist/SocialSignInButtons.js +2 -2
- package/dist/UserMenu.js +2 -2
- package/dist/createAuthClient.d.ts +1 -1
- package/dist/createAuthClient.d.ts.map +1 -1
- package/dist/createAuthClient.js +36 -4
- package/dist/createAuthenticatedFetch.d.ts +9 -9
- package/dist/createAuthenticatedFetch.d.ts.map +1 -1
- package/dist/createAuthenticatedFetch.js +49 -37
- package/dist/index.d.ts +20 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -17
- package/dist/invitation-status.d.ts +59 -0
- package/dist/invitation-status.d.ts.map +1 -0
- package/dist/invitation-status.js +32 -0
- package/dist/types.d.ts +11 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/useAuth.d.ts +1 -1
- package/dist/useAuth.d.ts.map +1 -1
- package/dist/useAuth.js +5 -1
- package/dist/useWorkspaceAdminStatus.d.ts +85 -0
- package/dist/useWorkspaceAdminStatus.d.ts.map +1 -0
- package/dist/useWorkspaceAdminStatus.js +102 -0
- package/package.json +4 -4
- package/dist/useIsWorkspaceAdmin.d.ts +0 -21
- package/dist/useIsWorkspaceAdmin.d.ts.map +0 -1
- package/dist/useIsWorkspaceAdmin.js +0 -47
|
@@ -15,15 +15,13 @@ export interface AuthenticatedAdapterOptions {
|
|
|
15
15
|
[key: string]: unknown;
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
18
|
+
* Re-exported from its own module so this file stays the WIRE lane and the
|
|
19
|
+
* storage lane has one home. `ActiveOrganizationStorage` moved out when it
|
|
20
|
+
* gained per-user scoping (objectui#5664); the export identity is unchanged,
|
|
21
|
+
* so `@object-ui/auth`'s barrel, this package's tests and every consumer
|
|
22
|
+
* import the same symbol from the same place they did before.
|
|
20
23
|
*/
|
|
21
|
-
export
|
|
22
|
-
_memoryValue: string | null;
|
|
23
|
-
get(): string | null;
|
|
24
|
-
set(orgId: string): void;
|
|
25
|
-
clear(): void;
|
|
26
|
-
};
|
|
24
|
+
export { ActiveOrganizationStorage, SessionUserScope, purgePreviousUserClientState } from './ActiveOrganizationStorage.js';
|
|
27
25
|
export interface CreateAuthenticatedFetchOptions {
|
|
28
26
|
/**
|
|
29
27
|
* When true, requests whose URL resolves to a different origin than the
|
|
@@ -39,7 +37,9 @@ export interface CreateAuthenticatedFetchOptions {
|
|
|
39
37
|
/**
|
|
40
38
|
* Creates an authenticated fetch wrapper that injects the Bearer token
|
|
41
39
|
* from localStorage into every request to the ObjectStack API.
|
|
42
|
-
* Also injects X-Tenant-ID header when an active organization is set
|
|
40
|
+
* Also injects X-Tenant-ID header when an active organization is set — see the
|
|
41
|
+
* "The `X-Tenant-ID` edge contract" section of this package's README for what
|
|
42
|
+
* that header means, who reads it, and the window in which it is not sent.
|
|
43
43
|
*
|
|
44
44
|
* @example
|
|
45
45
|
* ```ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createAuthenticatedFetch.d.ts","sourceRoot":"","sources":["../src/createAuthenticatedFetch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"createAuthenticatedFetch.d.ts","sourceRoot":"","sources":["../src/createAuthenticatedFetch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,OAAO,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAE3H,MAAM,WAAW,+BAA+B;IAC9C;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAYD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,CAAC,EAAE,+BAA+B,GACxC,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CA+GrE"}
|
|
@@ -5,43 +5,17 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
|
-
import { TokenStorage } from './createAuthClient';
|
|
9
|
-
import { authGateEvents, detectAuthGate } from './auth-gate-events';
|
|
10
|
-
|
|
8
|
+
import { TokenStorage } from './createAuthClient.js';
|
|
9
|
+
import { authGateEvents, detectAuthGate } from './auth-gate-events.js';
|
|
10
|
+
import { ActiveOrganizationStorage } from './ActiveOrganizationStorage.js';
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* Re-exported from its own module so this file stays the WIRE lane and the
|
|
13
|
+
* storage lane has one home. `ActiveOrganizationStorage` moved out when it
|
|
14
|
+
* gained per-user scoping (objectui#5664); the export identity is unchanged,
|
|
15
|
+
* so `@object-ui/auth`'s barrel, this package's tests and every consumer
|
|
16
|
+
* import the same symbol from the same place they did before.
|
|
14
17
|
*/
|
|
15
|
-
export
|
|
16
|
-
_memoryValue: null,
|
|
17
|
-
get() {
|
|
18
|
-
try {
|
|
19
|
-
if (typeof localStorage !== 'undefined') {
|
|
20
|
-
return localStorage.getItem(ACTIVE_ORG_STORAGE_KEY);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
catch { /* SSR / test */ }
|
|
24
|
-
return this._memoryValue;
|
|
25
|
-
},
|
|
26
|
-
set(orgId) {
|
|
27
|
-
this._memoryValue = orgId;
|
|
28
|
-
try {
|
|
29
|
-
if (typeof localStorage !== 'undefined') {
|
|
30
|
-
localStorage.setItem(ACTIVE_ORG_STORAGE_KEY, orgId);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
catch { /* SSR / test */ }
|
|
34
|
-
},
|
|
35
|
-
clear() {
|
|
36
|
-
this._memoryValue = null;
|
|
37
|
-
try {
|
|
38
|
-
if (typeof localStorage !== 'undefined') {
|
|
39
|
-
localStorage.removeItem(ACTIVE_ORG_STORAGE_KEY);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
catch { /* SSR / test */ }
|
|
43
|
-
},
|
|
44
|
-
};
|
|
18
|
+
export { ActiveOrganizationStorage, SessionUserScope, purgePreviousUserClientState } from './ActiveOrganizationStorage.js';
|
|
45
19
|
/** True when `url` resolves to a different origin than the current page. */
|
|
46
20
|
function isCrossOrigin(url) {
|
|
47
21
|
if (typeof window === 'undefined' || !window.location)
|
|
@@ -56,7 +30,9 @@ function isCrossOrigin(url) {
|
|
|
56
30
|
/**
|
|
57
31
|
* Creates an authenticated fetch wrapper that injects the Bearer token
|
|
58
32
|
* from localStorage into every request to the ObjectStack API.
|
|
59
|
-
* Also injects X-Tenant-ID header when an active organization is set
|
|
33
|
+
* Also injects X-Tenant-ID header when an active organization is set — see the
|
|
34
|
+
* "The `X-Tenant-ID` edge contract" section of this package's README for what
|
|
35
|
+
* that header means, who reads it, and the window in which it is not sent.
|
|
60
36
|
*
|
|
61
37
|
* @example
|
|
62
38
|
* ```ts
|
|
@@ -83,7 +59,43 @@ export function createAuthenticatedFetch(options) {
|
|
|
83
59
|
if (token && isApiCall) {
|
|
84
60
|
headers.set('Authorization', `Bearer ${token}`);
|
|
85
61
|
}
|
|
86
|
-
//
|
|
62
|
+
// ── `X-Tenant-ID` — the edge routing contract (objectui#5279) ────────
|
|
63
|
+
//
|
|
64
|
+
// WHAT IT MEANS. A routing hint for the hosting edge: "this request belongs
|
|
65
|
+
// to tenant <id>". The value is the better-auth `activeOrganizationId` the
|
|
66
|
+
// session already carries. It is NOT an identity claim, NOT an
|
|
67
|
+
// authorization input, and NOT what scopes rows.
|
|
68
|
+
//
|
|
69
|
+
// DO NOT DELETE THIS ON THE STRENGTH OF A GREP. The framework
|
|
70
|
+
// (`objectstack`) does not read it: `resolveAuthzContext` takes `tenantId`
|
|
71
|
+
// from the API-key principal or `session.activeOrganizationId` and never
|
|
72
|
+
// from a header, and environment routing reads the hostname and
|
|
73
|
+
// `X-Environment-Id`. So a search confined to this repo plus the framework
|
|
74
|
+
// finds zero consumers and reads as "dead stamp" — which is the false
|
|
75
|
+
// premise objectui#5279 was filed on. The consumer is in the CLOUD repo,
|
|
76
|
+
// which neither checkout contains: `service-tenant`'s `tenant-context.ts`
|
|
77
|
+
// resolves the header, and `tenant-router`'s `turso-multi-tenant.zod.ts`
|
|
78
|
+
// configures that resolution. The configuration contract IS readable from
|
|
79
|
+
// here — `TenantRoutingConfigSchema` in `@objectstack/spec/cloud` defaults
|
|
80
|
+
// `tenantHeaderName` to `X-Tenant-ID` and ranks `header` SECOND of six
|
|
81
|
+
// identification sources, behind `subdomain`.
|
|
82
|
+
//
|
|
83
|
+
// THE UNSTAMPED-FIRST-REQUEST GAP. `ActiveOrganizationStorage` is filled
|
|
84
|
+
// only after AuthProvider's async organization chain resolves, so early
|
|
85
|
+
// requests go out with the header ABSENT — never present-and-empty. A
|
|
86
|
+
// reader must fall through to its next identification source rather than
|
|
87
|
+
// fail closed. Nothing about row visibility rides on this: the framework
|
|
88
|
+
// scopes from the session, so a response computed inside the window is
|
|
89
|
+
// still computed for the right tenant.
|
|
90
|
+
//
|
|
91
|
+
// Not gated on `isApiCall`, unlike `Authorization` and `Accept-Language`
|
|
92
|
+
// above — recorded as the behaviour that ships, not endorsed; the
|
|
93
|
+
// asymmetry is reported on objectui#5279 for triage to route. A wrapper
|
|
94
|
+
// built with `sameOriginOnly` short-circuits every cross-origin request
|
|
95
|
+
// before this line.
|
|
96
|
+
//
|
|
97
|
+
// Full contract, including what a reader may and may not assume: this
|
|
98
|
+
// package's README, "The `X-Tenant-ID` edge contract".
|
|
87
99
|
const activeOrgId = ActiveOrganizationStorage.get();
|
|
88
100
|
if (activeOrgId) {
|
|
89
101
|
headers.set('X-Tenant-ID', activeOrgId);
|
package/dist/index.d.ts
CHANGED
|
@@ -19,23 +19,24 @@
|
|
|
19
19
|
*
|
|
20
20
|
* @packageDocumentation
|
|
21
21
|
*/
|
|
22
|
-
export { AuthProvider, type AuthProviderProps } from './AuthProvider';
|
|
23
|
-
export { useAuth } from './useAuth';
|
|
24
|
-
export {
|
|
25
|
-
export { AuthGuard, type AuthGuardProps } from './AuthGuard';
|
|
26
|
-
export { AuthShell, type AuthShellProps, type AuthShellBrandPanel } from './AuthShell';
|
|
27
|
-
export { LoginForm, type LoginFormProps, type LoginFormLabels } from './LoginForm';
|
|
28
|
-
export { RegisterForm, type RegisterFormProps, type RegisterFormLabels } from './RegisterForm';
|
|
29
|
-
export { ForgotPasswordForm, type ForgotPasswordFormProps, type ForgotPasswordFormLabels } from './ForgotPasswordForm';
|
|
30
|
-
export { SocialSignInButtons, type SocialSignInButtonsProps } from './SocialSignInButtons';
|
|
31
|
-
export { UserMenu, type UserMenuProps } from './UserMenu';
|
|
32
|
-
export { PreviewBanner, type PreviewBannerProps } from './PreviewBanner';
|
|
33
|
-
export { createAuthClient, TokenStorage } from './createAuthClient';
|
|
34
|
-
export { normalizePhoneIdentifier, looksLikePhoneIdentifier } from './phone-identifier';
|
|
35
|
-
export { createAuthenticatedFetch, ActiveOrganizationStorage, type AuthenticatedAdapterOptions } from './createAuthenticatedFetch';
|
|
36
|
-
export { getUserInitials } from './types';
|
|
37
|
-
export { ORG_ROLE_OWNER, ORG_ROLE_ADMIN, ORG_ROLE_DELEGATED_ADMIN, ORG_ROLE_MEMBER, ORG_ROLES, ORG_ROLE_LABELS, orgRoleGrade, invitableOrgRoles, assignableOrgRoles, type OrgRole, } from './org-roles';
|
|
38
|
-
export {
|
|
39
|
-
export
|
|
40
|
-
export type {
|
|
22
|
+
export { AuthProvider, type AuthProviderProps } from './AuthProvider.js';
|
|
23
|
+
export { useAuth } from './useAuth.js';
|
|
24
|
+
export { useWorkspaceAdminStatus, type WorkspaceAdminStatus } from './useWorkspaceAdminStatus.js';
|
|
25
|
+
export { AuthGuard, type AuthGuardProps } from './AuthGuard.js';
|
|
26
|
+
export { AuthShell, type AuthShellProps, type AuthShellBrandPanel } from './AuthShell.js';
|
|
27
|
+
export { LoginForm, type LoginFormProps, type LoginFormLabels } from './LoginForm.js';
|
|
28
|
+
export { RegisterForm, type RegisterFormProps, type RegisterFormLabels } from './RegisterForm.js';
|
|
29
|
+
export { ForgotPasswordForm, type ForgotPasswordFormProps, type ForgotPasswordFormLabels } from './ForgotPasswordForm.js';
|
|
30
|
+
export { SocialSignInButtons, type SocialSignInButtonsProps } from './SocialSignInButtons.js';
|
|
31
|
+
export { UserMenu, type UserMenuProps } from './UserMenu.js';
|
|
32
|
+
export { PreviewBanner, type PreviewBannerProps } from './PreviewBanner.js';
|
|
33
|
+
export { createAuthClient, TokenStorage } from './createAuthClient.js';
|
|
34
|
+
export { normalizePhoneIdentifier, looksLikePhoneIdentifier } from './phone-identifier.js';
|
|
35
|
+
export { createAuthenticatedFetch, ActiveOrganizationStorage, type AuthenticatedAdapterOptions } from './createAuthenticatedFetch.js';
|
|
36
|
+
export { getUserInitials } from './types.js';
|
|
37
|
+
export { ORG_ROLE_OWNER, ORG_ROLE_ADMIN, ORG_ROLE_DELEGATED_ADMIN, ORG_ROLE_MEMBER, ORG_ROLES, ORG_ROLE_LABELS, orgRoleGrade, invitableOrgRoles, assignableOrgRoles, type OrgRole, } from './org-roles.js';
|
|
38
|
+
export { AUTH_INVITATION_STATUSES, isAuthInvitationStatus, type AuthInvitationStatus, } from './invitation-status.js';
|
|
39
|
+
export { AUTH_FIELD_LABEL_CLASS, AUTH_INPUT_CLASS, AUTH_LINK_CLASS, AUTH_PRIMARY_BUTTON_CLASS, AuthAlertIcon, AuthCheckIcon, AuthDivider, AuthErrorBanner, AuthFormHeader, AuthMailIcon, AuthSpinner, } from './authStyles.js';
|
|
40
|
+
export type { AuthUser, AuthClientSession, AuthState, AuthClient, AuthClientConfig, AuthLinkComponentProps, AuthProviderOptions, PreviewModeOptions, SignInCredentials, SignUpData, AuthOrganization, AuthOrganizationMember, AuthInvitation, AuthSocialProvider, AuthPublicConfig, SignInWithProviderOptions, TenancyPosture, DelegableScope, } from './types.js';
|
|
41
|
+
export type { AuthContextValue } from './AuthContext.js';
|
|
41
42
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAOvC,OAAO,EAAE,uBAAuB,EAAE,KAAK,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAClG,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1F,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAClG,OAAO,EAAE,kBAAkB,EAAE,KAAK,uBAAuB,EAAE,KAAK,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAC1H,OAAO,EAAE,mBAAmB,EAAE,KAAK,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAC9F,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAC3F,OAAO,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,KAAK,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AACtI,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAO7C,OAAO,EACL,cAAc,EACd,cAAc,EACd,wBAAwB,EACxB,eAAe,EACf,SAAS,EACT,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,OAAO,GACb,MAAM,gBAAgB,CAAC;AAMxB,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,KAAK,oBAAoB,GAC1B,MAAM,wBAAwB,CAAC;AAIhC,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,yBAAyB,EACzB,aAAa,EACb,aAAa,EACb,WAAW,EACX,eAAe,EACf,cAAc,EACd,YAAY,EACZ,WAAW,GACZ,MAAM,iBAAiB,CAAC;AAGzB,YAAY,EACV,QAAQ,EACR,iBAAiB,EACjB,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,sBAAsB,EACtB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -19,27 +19,38 @@
|
|
|
19
19
|
*
|
|
20
20
|
* @packageDocumentation
|
|
21
21
|
*/
|
|
22
|
-
export { AuthProvider } from './AuthProvider';
|
|
23
|
-
export { useAuth } from './useAuth';
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
export
|
|
29
|
-
|
|
30
|
-
export {
|
|
31
|
-
export {
|
|
32
|
-
export {
|
|
33
|
-
export {
|
|
34
|
-
export {
|
|
35
|
-
export {
|
|
36
|
-
export {
|
|
22
|
+
export { AuthProvider } from './AuthProvider.js';
|
|
23
|
+
export { useAuth } from './useAuth.js';
|
|
24
|
+
// objectui#5619 — replaces `useIsWorkspaceAdmin(): boolean`, which had no way
|
|
25
|
+
// to say "not resolved yet" and so answered "not an admin" about an
|
|
26
|
+
// administrator whose adminship lives only in the active member row. The old
|
|
27
|
+
// name is REMOVED rather than kept alongside: a caller that misses the third
|
|
28
|
+
// state is the whole defect, and a deleted export makes that a compile error
|
|
29
|
+
// instead of a silent access-denied screen.
|
|
30
|
+
export { useWorkspaceAdminStatus } from './useWorkspaceAdminStatus.js';
|
|
31
|
+
export { AuthGuard } from './AuthGuard.js';
|
|
32
|
+
export { AuthShell } from './AuthShell.js';
|
|
33
|
+
export { LoginForm } from './LoginForm.js';
|
|
34
|
+
export { RegisterForm } from './RegisterForm.js';
|
|
35
|
+
export { ForgotPasswordForm } from './ForgotPasswordForm.js';
|
|
36
|
+
export { SocialSignInButtons } from './SocialSignInButtons.js';
|
|
37
|
+
export { UserMenu } from './UserMenu.js';
|
|
38
|
+
export { PreviewBanner } from './PreviewBanner.js';
|
|
39
|
+
export { createAuthClient, TokenStorage } from './createAuthClient.js';
|
|
40
|
+
export { normalizePhoneIdentifier, looksLikePhoneIdentifier } from './phone-identifier.js';
|
|
41
|
+
export { createAuthenticatedFetch, ActiveOrganizationStorage } from './createAuthenticatedFetch.js';
|
|
42
|
+
export { getUserInitials } from './types.js';
|
|
37
43
|
// Organization membership-role vocabulary — a CLOSED, framework-owned list of
|
|
38
44
|
// four (framework ADR-0108), re-exported from `@objectstack/spec`'s
|
|
39
45
|
// `BUILTIN_MEMBERSHIP_ROLES` so it cannot drift — plus the labels and
|
|
40
46
|
// narrowing helpers every org screen shares, which stay console-owned
|
|
41
47
|
// (see `org-roles.ts` for the boundary).
|
|
42
|
-
export { ORG_ROLE_OWNER, ORG_ROLE_ADMIN, ORG_ROLE_DELEGATED_ADMIN, ORG_ROLE_MEMBER, ORG_ROLES, ORG_ROLE_LABELS, orgRoleGrade, invitableOrgRoles, assignableOrgRoles, } from './org-roles';
|
|
48
|
+
export { ORG_ROLE_OWNER, ORG_ROLE_ADMIN, ORG_ROLE_DELEGATED_ADMIN, ORG_ROLE_MEMBER, ORG_ROLES, ORG_ROLE_LABELS, orgRoleGrade, invitableOrgRoles, assignableOrgRoles, } from './org-roles.js';
|
|
49
|
+
// Invitation lifecycle vocabulary — a CLOSED set of four, bound to better-auth's
|
|
50
|
+
// own `InvitationStatus` so it cannot drift, plus the narrowing guard the wire
|
|
51
|
+
// boundary uses. Exported because a screen switching on `AuthInvitation.status`
|
|
52
|
+
// needs the union by name (objectui#3879).
|
|
53
|
+
export { AUTH_INVITATION_STATUSES, isAuthInvitationStatus, } from './invitation-status.js';
|
|
43
54
|
// Shared auth form primitives — exposed so consumers can build custom forms
|
|
44
55
|
// that match the look of LoginForm / RegisterForm / ForgotPasswordForm.
|
|
45
|
-
export { AUTH_FIELD_LABEL_CLASS, AUTH_INPUT_CLASS, AUTH_LINK_CLASS, AUTH_PRIMARY_BUTTON_CLASS, AuthAlertIcon, AuthCheckIcon, AuthDivider, AuthErrorBanner, AuthFormHeader, AuthMailIcon, AuthSpinner, } from './authStyles';
|
|
56
|
+
export { AUTH_FIELD_LABEL_CLASS, AUTH_INPUT_CLASS, AUTH_LINK_CLASS, AUTH_PRIMARY_BUTTON_CLASS, AuthAlertIcon, AuthCheckIcon, AuthDivider, AuthErrorBanner, AuthFormHeader, AuthMailIcon, AuthSpinner, } from './authStyles.js';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Invitation status vocabulary — the console's ONE entry point for it.
|
|
10
|
+
*
|
|
11
|
+
* ## Why this is a module and not a doc comment
|
|
12
|
+
*
|
|
13
|
+
* `AuthInvitation.status` was declared as an open `string` while its own doc
|
|
14
|
+
* comment enumerated exactly four members (objectui#3879). A comment cannot be
|
|
15
|
+
* enforced, so every consumer had to be liberal in turn: `InvitationsPage`
|
|
16
|
+
* carried a `default: 'secondary'` arm in its badge-variant switch and a
|
|
17
|
+
* `defaultValue: inv.status` that would render the raw wire string as UI copy —
|
|
18
|
+
* in all ten packs — for any value the enumeration did not cover. Declared =
|
|
19
|
+
* enforced (AGENTS.md #0.1): the union now lives in the type, and the wire
|
|
20
|
+
* boundary in `createAuthClient` is the one place an unvalidated string may
|
|
21
|
+
* become one.
|
|
22
|
+
*
|
|
23
|
+
* ## The vocabulary is CLOSED — and derived, not mirrored
|
|
24
|
+
*
|
|
25
|
+
* The producer is better-auth's organization plugin, whose own
|
|
26
|
+
* `InvitationStatus` is `'pending' | 'accepted' | 'rejected' | 'canceled'`
|
|
27
|
+
* (`better-auth/client/plugins`; the framework stores it in
|
|
28
|
+
* `sys_invitation.status`). This module BINDS that type instead of restating it,
|
|
29
|
+
* for the same reason `org-roles.ts` binds the spec's
|
|
30
|
+
* `BUILTIN_MEMBERSHIP_ROLES`: a member-for-member copy is precisely the state
|
|
31
|
+
* one upstream release away from drifting silently.
|
|
32
|
+
*
|
|
33
|
+
* The runtime list is derived from a total `Record` keyed by that union, so the
|
|
34
|
+
* compile-time half and the runtime half cannot disagree — a fifth status
|
|
35
|
+
* upstream fails to compile HERE (the map is missing a key) rather than slipping
|
|
36
|
+
* past the boundary check and out onto a badge.
|
|
37
|
+
*
|
|
38
|
+
* What stays LOCAL, deliberately: everything about *display*. The filter tabs'
|
|
39
|
+
* `StatusFilter` (which adds an `all` pseudo-member) and the badge variants are
|
|
40
|
+
* screen concerns and live with the screen — the same boundary `org-roles.ts`
|
|
41
|
+
* draws for its labels and grade ladder.
|
|
42
|
+
*/
|
|
43
|
+
import type { InvitationStatus } from 'better-auth/client/plugins';
|
|
44
|
+
/**
|
|
45
|
+
* Status an organization invitation can carry — better-auth's own union, bound
|
|
46
|
+
* rather than copied.
|
|
47
|
+
*/
|
|
48
|
+
export type AuthInvitationStatus = InvitationStatus;
|
|
49
|
+
/** Every status an invitation can carry, in the order the screens list them. */
|
|
50
|
+
export declare const AUTH_INVITATION_STATUSES: readonly AuthInvitationStatus[];
|
|
51
|
+
/**
|
|
52
|
+
* Narrow an unvalidated wire value onto the closed status set.
|
|
53
|
+
*
|
|
54
|
+
* The ONE place a `string` may become an `AuthInvitationStatus`. Everything
|
|
55
|
+
* downstream reads the narrowed type and therefore needs no fallback arm — which
|
|
56
|
+
* is the whole point: a tolerant consumer is where an unexpected value hides.
|
|
57
|
+
*/
|
|
58
|
+
export declare function isAuthInvitationStatus(value: unknown): value is AuthInvitationStatus;
|
|
59
|
+
//# sourceMappingURL=invitation-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invitation-status.d.ts","sourceRoot":"","sources":["../src/invitation-status.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,CAAC;AAcpD,gFAAgF;AAChF,eAAO,MAAM,wBAAwB,EAAE,SAAS,oBAAoB,EACrC,CAAC;AAKhC;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,CAEpF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Total map over the union — the compile-time half of the pin. Values are the
|
|
10
|
+
* members themselves so the runtime list below is DERIVED rather than restated
|
|
11
|
+
* (one literal list, not two).
|
|
12
|
+
*/
|
|
13
|
+
const STATUS_MEMBERS = {
|
|
14
|
+
pending: 'pending',
|
|
15
|
+
accepted: 'accepted',
|
|
16
|
+
rejected: 'rejected',
|
|
17
|
+
canceled: 'canceled',
|
|
18
|
+
};
|
|
19
|
+
/** Every status an invitation can carry, in the order the screens list them. */
|
|
20
|
+
export const AUTH_INVITATION_STATUSES = Object.values(STATUS_MEMBERS);
|
|
21
|
+
/** Membership test backing the guard. `Set` so the check stays O(1) per row. */
|
|
22
|
+
const STATUS_LOOKUP = new Set(AUTH_INVITATION_STATUSES);
|
|
23
|
+
/**
|
|
24
|
+
* Narrow an unvalidated wire value onto the closed status set.
|
|
25
|
+
*
|
|
26
|
+
* The ONE place a `string` may become an `AuthInvitationStatus`. Everything
|
|
27
|
+
* downstream reads the narrowed type and therefore needs no fallback arm — which
|
|
28
|
+
* is the whole point: a tolerant consumer is where an unexpected value hides.
|
|
29
|
+
*/
|
|
30
|
+
export function isAuthInvitationStatus(value) {
|
|
31
|
+
return typeof value === 'string' && STATUS_LOOKUP.has(value);
|
|
32
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import type React from 'react';
|
|
9
9
|
import type { AuthUser as SpecAuthUser, DelegableScope, DelegableAdminScope } from '@objectstack/spec/contracts';
|
|
10
10
|
import type { TenancyPosture } from '@objectstack/spec/security';
|
|
11
|
+
import type { AuthInvitationStatus } from './invitation-status.js';
|
|
11
12
|
/**
|
|
12
13
|
* Authentication types for @object-ui/auth
|
|
13
14
|
*/
|
|
@@ -55,8 +56,6 @@ export interface AuthUser extends SpecAuthUser {
|
|
|
55
56
|
image?: string;
|
|
56
57
|
/** Primary role */
|
|
57
58
|
role?: string;
|
|
58
|
-
/** All assigned roles */
|
|
59
|
-
roles?: string[];
|
|
60
59
|
/** Email verification status */
|
|
61
60
|
emailVerified?: boolean;
|
|
62
61
|
/** Additional user metadata */
|
|
@@ -442,8 +441,16 @@ export interface AuthInvitation {
|
|
|
442
441
|
email: string;
|
|
443
442
|
/** Role to be granted upon acceptance */
|
|
444
443
|
role: string;
|
|
445
|
-
/**
|
|
446
|
-
|
|
444
|
+
/**
|
|
445
|
+
* Lifecycle status, as the CLOSED set better-auth stores.
|
|
446
|
+
*
|
|
447
|
+
* Was an open `string` with the four members living in this comment, which
|
|
448
|
+
* left every consumer to be liberal about the fifth value that comment could
|
|
449
|
+
* not forbid (objectui#3879). The union is `AuthInvitationStatus` now, and
|
|
450
|
+
* `createAuthClient` narrows the wire value onto it at the boundary — so a
|
|
451
|
+
* screen reading this field can switch on it exhaustively.
|
|
452
|
+
*/
|
|
453
|
+
status: AuthInvitationStatus;
|
|
447
454
|
/** Expiration timestamp */
|
|
448
455
|
expiresAt?: string;
|
|
449
456
|
/** ID of the inviting user */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EACV,QAAQ,IAAI,YAAY,EACxB,cAAc,EACd,mBAAmB,EACpB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/useAuth.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
|
-
import { type AuthContextValue } from './AuthContext';
|
|
8
|
+
import { type AuthContextValue } from './AuthContext.js';
|
|
9
9
|
/**
|
|
10
10
|
* Hook to access authentication state and methods.
|
|
11
11
|
* Must be used within an AuthProvider.
|
package/dist/useAuth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAuth.d.ts","sourceRoot":"","sources":["../src/useAuth.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAW,KAAK,gBAAgB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"useAuth.d.ts","sourceRoot":"","sources":["../src/useAuth.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAW,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAElE;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,IAAI,gBAAgB,CAiE1C"}
|
package/dist/useAuth.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
import { useContext } from 'react';
|
|
9
|
-
import { AuthCtx } from './AuthContext';
|
|
9
|
+
import { AuthCtx } from './AuthContext.js';
|
|
10
10
|
/**
|
|
11
11
|
* Hook to access authentication state and methods.
|
|
12
12
|
* Must be used within an AuthProvider.
|
|
@@ -60,6 +60,10 @@ export function useAuth() {
|
|
|
60
60
|
activeOrganization: null,
|
|
61
61
|
activeMember: null,
|
|
62
62
|
isOrganizationsLoading: false,
|
|
63
|
+
// Nothing to resolve without a provider — same reasoning as `isLoading`
|
|
64
|
+
// above, which is `false` here for the same reason. A consumer gating on
|
|
65
|
+
// this must render through in a provider-less embed, not hang.
|
|
66
|
+
isMembershipResolved: true,
|
|
63
67
|
switchOrganization: async () => { throw new Error('useAuth must be used within an AuthProvider'); },
|
|
64
68
|
createOrganization: async () => { throw new Error('useAuth must be used within an AuthProvider'); },
|
|
65
69
|
refreshOrganizations: async () => { throw new Error('useAuth must be used within an AuthProvider'); },
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* The workspace-admin verdict AND whether it is worth acting on yet.
|
|
10
|
+
*
|
|
11
|
+
* These are two different facts and they were one boolean until objectui#5619.
|
|
12
|
+
* See {@link useWorkspaceAdminStatus} for why collapsing them was a defect.
|
|
13
|
+
*/
|
|
14
|
+
export interface WorkspaceAdminStatus {
|
|
15
|
+
/**
|
|
16
|
+
* True only when adminship is CONFIRMED by one of the three legs below.
|
|
17
|
+
* While `isResolved` is false this is `false` because nothing has said
|
|
18
|
+
* otherwise yet — NOT because the viewer is known not to be an admin.
|
|
19
|
+
*/
|
|
20
|
+
isAdmin: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Whether every input `isAdmin` depends on has arrived. Gate any branch
|
|
23
|
+
* whose wrong side is expensive — a refusal screen, a `<Navigate>`, a nav
|
|
24
|
+
* entry that would have to be added back — on this being true.
|
|
25
|
+
*/
|
|
26
|
+
isResolved: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Whether the current user has owner/admin privileges, and whether that answer
|
|
30
|
+
* has finished resolving.
|
|
31
|
+
*
|
|
32
|
+
* Sources considered (any one is sufficient):
|
|
33
|
+
* - The active organization member row (multi-tenant mode).
|
|
34
|
+
* - The top-level `user.role` scalar from the session — legacy deployments
|
|
35
|
+
* that still store an admin role on the user row.
|
|
36
|
+
* - `user.positions[]` from the session — the canonical identity/position
|
|
37
|
+
* names the server derives (ADR-0068 D1/D2, renamed from `roles` by
|
|
38
|
+
* ADR-0090 D3). This is the ONLY leg that sees a platform administrator
|
|
39
|
+
* whose adminship comes from the `admin_full_access` permission set: on a
|
|
40
|
+
* single-tenant deployment there is no member row to read (leg 1), and the
|
|
41
|
+
* server deliberately no longer overwrites `user.role` (leg 2), so
|
|
42
|
+
* `positions` carrying `platform_admin` is the whole signal. Measured on a
|
|
43
|
+
* live protocol-17 server in objectui#5389; pinned by
|
|
44
|
+
* `__tests__/workspaceAdminPositions-5389.test.tsx`.
|
|
45
|
+
*
|
|
46
|
+
* `positions` is the ONE published spelling. It is deliberately not read
|
|
47
|
+
* alongside the retired `roles` (ADR-0090 D3 renamed with no deprecation
|
|
48
|
+
* window and bans resurrecting the old name as a fallback), and not alongside
|
|
49
|
+
* the derived `user.isPlatformAdmin` either — that flag is computed by the
|
|
50
|
+
* server as `'platform_admin' in positions` from the same expression, so
|
|
51
|
+
* reading both would be two spellings for one fact with no way to disagree
|
|
52
|
+
* usefully and every way to drift.
|
|
53
|
+
*
|
|
54
|
+
* In preview-mode / no-auth-enabled mode the provider seeds an admin user,
|
|
55
|
+
* so this returns `isAdmin: true` for dev/demo setups.
|
|
56
|
+
*
|
|
57
|
+
* ## Why this returns a pair and not a boolean (objectui#5619)
|
|
58
|
+
*
|
|
59
|
+
* It used to return a bare `boolean`, which gave "not resolved yet" and
|
|
60
|
+
* "resolved: not an admin" the same answer — `false`. Leg 1 is not settled
|
|
61
|
+
* when a console page first mounts: `AuthProvider.refreshActiveMember` runs
|
|
62
|
+
* from its own effect, keyed on `activeOrganization`, which itself appears
|
|
63
|
+
* only after `listOrganizations()` → `getActiveOrganization()` (→ the ADR-0081
|
|
64
|
+
* single-membership `setActiveOrganization()` repair) resolve. So an
|
|
65
|
+
* administrator whose adminship lives ONLY in the member row rendered at least
|
|
66
|
+
* once as a non-admin, and every gate downstream acted on it: two marketplace
|
|
67
|
+
* surfaces painted `MarketplaceAccessDenied` at a real administrator, the
|
|
68
|
+
* console chrome dropped and re-added a nav entry, and `AppContent` fired a
|
|
69
|
+
* `<Navigate to="/home" replace>` that the later flip cannot undo.
|
|
70
|
+
*
|
|
71
|
+
* Legs 2 and 3 DO cover that viewer whenever the session was minted with an
|
|
72
|
+
* active organization stamped on it — framework `auth-manager.ts` reads
|
|
73
|
+
* `session.activeOrganizationId` and, when it is set, maps the member row into
|
|
74
|
+
* `positions[]` as `org_owner`/`org_admin`. The window is therefore not "every
|
|
75
|
+
* tenant admin" as first reported, but "every session that reaches the console
|
|
76
|
+
* without that stamp", which is exactly the path `refreshOrganizations`'
|
|
77
|
+
* ADR-0081 repair exists to serve.
|
|
78
|
+
*
|
|
79
|
+
* `isResolved` is deliberately true the moment `isAdmin` is true: a confirmed
|
|
80
|
+
* admin is a final answer, and the legs still in flight can only agree with it.
|
|
81
|
+
* Callers therefore never wait on a verdict they already have — an admin
|
|
82
|
+
* detected through `positions` pays nothing for this gate.
|
|
83
|
+
*/
|
|
84
|
+
export declare function useWorkspaceAdminStatus(): WorkspaceAdminStatus;
|
|
85
|
+
//# sourceMappingURL=useWorkspaceAdminStatus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWorkspaceAdminStatus.d.ts","sourceRoot":"","sources":["../src/useWorkspaceAdminStatus.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA8BH;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,wBAAgB,uBAAuB,IAAI,oBAAoB,CAgB9D"}
|