@objectstack/plugin-auth 4.0.5 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -3,6 +3,7 @@ import { AuthConfig, OidcProvidersConfig } from '@objectstack/spec/system';
3
3
  export { AuthConfig, AuthPluginConfig, AuthProviderConfig } from '@objectstack/spec/system';
4
4
  import * as better_auth from 'better-auth';
5
5
  import { Auth } from 'better-auth';
6
+ import { IEmailService } from '@objectstack/spec/contracts';
6
7
  import * as better_auth_adapters from 'better-auth/adapters';
7
8
  import { CleanedWhere } from 'better-auth/adapters';
8
9
 
@@ -21,6 +22,23 @@ interface AuthPluginOptions extends Partial<AuthConfig> {
21
22
  * @default '/api/v1/auth'
22
23
  */
23
24
  basePath?: string;
25
+ /**
26
+ * Override the datasource that owns the identity tables (sys_user,
27
+ * sys_session, …) when AuthPlugin's manifest is registered.
28
+ *
29
+ * Defaults to `'cloud'` (control-plane DB) so the historical
30
+ * single-tenant control-plane behaviour is preserved. Per-project
31
+ * kernels in objectos pass `'default'` so identity tables live in the
32
+ * project's own database — each project owns its own users.
33
+ */
34
+ manifestDatasource?: string;
35
+ /**
36
+ * Application-specific organization roles to register with Better-Auth's
37
+ * organization plugin so invitations to those roles aren't rejected with
38
+ * ROLE_NOT_FOUND. Forwarded as-is to AuthManager. See
39
+ * {@link AuthManagerOptions.additionalOrgRoles} for details.
40
+ */
41
+ additionalOrgRoles?: string[];
24
42
  }
25
43
  /**
26
44
  * Authentication Plugin
@@ -109,6 +127,42 @@ interface AuthManagerOptions extends Partial<AuthConfig> {
109
127
  * Each entry is passed to better-auth's genericOAuth plugin.
110
128
  */
111
129
  oidcProviders?: OidcProvidersConfig;
130
+ /**
131
+ * Application-specific organization roles to register with Better-Auth's
132
+ * organization plugin. Each name becomes a valid role for invitations and
133
+ * member assignments without going through Better-Auth's default
134
+ * `owner|admin|member` whitelist.
135
+ *
136
+ * The ObjectStack SecurityPlugin handles real RBAC enforcement by matching
137
+ * these role names against `permission` metadata (PermissionSets / Profiles),
138
+ * so Better-Auth only needs to accept them as opaque strings. Each role is
139
+ * registered with the minimum access-control privileges (equivalent to
140
+ * Better-Auth's `member` role) so it cannot inadvertently grant org-level
141
+ * admin capabilities.
142
+ *
143
+ * Typical source: the union of `permission` metadata names that have
144
+ * `isProfile: true`, collected from the loaded stack at CLI boot.
145
+ *
146
+ * @example ['sales_rep', 'sales_manager', 'service_agent']
147
+ */
148
+ additionalOrgRoles?: string[];
149
+ /**
150
+ * Optional outbound email service used by better-auth callbacks
151
+ * (`sendResetPassword`, `sendVerificationEmail`, `sendInvitationEmail`,
152
+ * `sendMagicLink`). When omitted, those callbacks degrade to logging
153
+ * the action URL — keeping flows usable in pilots / local dev — but
154
+ * production deployments SHOULD wire one via `setEmailService()`.
155
+ *
156
+ * Resolved lazily through {@link AuthManager.getEmailService}; safe
157
+ * to set after construction. AuthPlugin wires this from the kernel
158
+ * service registry on `kernel:ready`.
159
+ */
160
+ emailService?: IEmailService;
161
+ /**
162
+ * Display name used by built-in auth email templates (`{{appName}}`
163
+ * placeholder). Defaults to `'ObjectStack'` when omitted.
164
+ */
165
+ appName?: string;
112
166
  }
113
167
  /**
114
168
  * Authentication Manager
@@ -170,6 +224,20 @@ declare class AuthManager {
170
224
  * a warning is emitted.
171
225
  */
172
226
  setRuntimeBaseUrl(url: string): void;
227
+ /**
228
+ * Inject (or replace) the outbound email service used by better-auth
229
+ * callbacks. Safe to call after construction but BEFORE the first
230
+ * request hits the auth handler — callbacks read this via
231
+ * {@link getEmailService} when invoked.
232
+ *
233
+ * AuthPlugin calls this on `kernel:ready` once `ctx.getService('email')`
234
+ * resolves. For tests / serverless, callers may invoke directly.
235
+ */
236
+ setEmailService(email: IEmailService | undefined): void;
237
+ /** @internal Used by callback closures. */
238
+ private getEmailService;
239
+ /** @internal `{{appName}}` placeholder value for built-in templates. */
240
+ private getAppName;
173
241
  /**
174
242
  * Get the underlying better-auth instance
175
243
  * Useful for advanced use cases
@@ -544,6 +612,29 @@ declare const AUTH_TWO_FACTOR_SCHEMA: {
544
612
  declare const AUTH_TWO_FACTOR_USER_FIELDS: {
545
613
  readonly twoFactorEnabled: "two_factor_enabled";
546
614
  };
615
+ /**
616
+ * Admin plugin adds platform-level admin fields to the `user` model.
617
+ *
618
+ * | camelCase (better-auth) | snake_case (ObjectStack) |
619
+ * |:------------------------|:-------------------------|
620
+ * | banReason | ban_reason |
621
+ * | banExpires | ban_expires |
622
+ *
623
+ * `role` and `banned` already have matching snake_case names and are
624
+ * therefore omitted from this mapping (better-auth's database hooks
625
+ * read them by the auto-derived column names).
626
+ */
627
+ declare const AUTH_ADMIN_USER_FIELDS: {
628
+ readonly banReason: "ban_reason";
629
+ readonly banExpires: "ban_expires";
630
+ };
631
+ /**
632
+ * Admin plugin adds an `impersonatedBy` field to the session model
633
+ * recording the operator user id when an admin impersonates someone.
634
+ */
635
+ declare const AUTH_ADMIN_SESSION_FIELDS: {
636
+ readonly impersonatedBy: "impersonated_by";
637
+ };
547
638
  /**
548
639
  * `@better-auth/oauth-provider` plugin `oauthClient` model mapping.
549
640
  *
@@ -753,6 +844,26 @@ declare function buildTwoFactorPluginSchema(): {
753
844
  };
754
845
  };
755
846
  };
847
+ /**
848
+ * Builds the `schema` option for better-auth's `admin()` plugin.
849
+ *
850
+ * The admin plugin extends the user model with `role`/`banned`/`banReason`/
851
+ * `banExpires` and the session model with `impersonatedBy`. Only the
852
+ * snake_case-differing fields are mapped explicitly.
853
+ */
854
+ declare function buildAdminPluginSchema(): {
855
+ user: {
856
+ fields: {
857
+ readonly banReason: "ban_reason";
858
+ readonly banExpires: "ban_expires";
859
+ };
860
+ };
861
+ session: {
862
+ fields: {
863
+ readonly impersonatedBy: "impersonated_by";
864
+ };
865
+ };
866
+ };
756
867
  /**
757
868
  * Builds the `schema` option for better-auth's `organization()` plugin.
758
869
  *
@@ -952,4 +1063,4 @@ declare function buildDeviceAuthorizationPluginSchema(): {
952
1063
  };
953
1064
  };
954
1065
 
955
- export { AUTH_ACCOUNT_CONFIG, AUTH_DEVICE_CODE_SCHEMA, AUTH_INVITATION_SCHEMA, AUTH_JWKS_SCHEMA, AUTH_MEMBER_SCHEMA, AUTH_MODEL_TO_PROTOCOL, AUTH_OAUTH_ACCESS_TOKEN_SCHEMA, AUTH_OAUTH_APPLICATION_SCHEMA, AUTH_OAUTH_CLIENT_SCHEMA, AUTH_OAUTH_CONSENT_SCHEMA, AUTH_OAUTH_REFRESH_TOKEN_SCHEMA, AUTH_ORGANIZATION_SCHEMA, AUTH_ORG_SESSION_FIELDS, AUTH_SESSION_CONFIG, AUTH_TEAM_MEMBER_SCHEMA, AUTH_TEAM_SCHEMA, AUTH_TWO_FACTOR_SCHEMA, AUTH_TWO_FACTOR_USER_FIELDS, AUTH_USER_CONFIG, AUTH_VERIFICATION_CONFIG, AuthManager, type AuthManagerOptions, AuthPlugin, type AuthPluginOptions, buildDeviceAuthorizationPluginSchema, buildJwtPluginSchema, buildOauthProviderPluginSchema, buildOidcProviderPluginSchema, buildOrganizationPluginSchema, buildTwoFactorPluginSchema, createObjectQLAdapter, createObjectQLAdapterFactory, resolveProtocolName };
1066
+ export { AUTH_ACCOUNT_CONFIG, AUTH_ADMIN_SESSION_FIELDS, AUTH_ADMIN_USER_FIELDS, AUTH_DEVICE_CODE_SCHEMA, AUTH_INVITATION_SCHEMA, AUTH_JWKS_SCHEMA, AUTH_MEMBER_SCHEMA, AUTH_MODEL_TO_PROTOCOL, AUTH_OAUTH_ACCESS_TOKEN_SCHEMA, AUTH_OAUTH_APPLICATION_SCHEMA, AUTH_OAUTH_CLIENT_SCHEMA, AUTH_OAUTH_CONSENT_SCHEMA, AUTH_OAUTH_REFRESH_TOKEN_SCHEMA, AUTH_ORGANIZATION_SCHEMA, AUTH_ORG_SESSION_FIELDS, AUTH_SESSION_CONFIG, AUTH_TEAM_MEMBER_SCHEMA, AUTH_TEAM_SCHEMA, AUTH_TWO_FACTOR_SCHEMA, AUTH_TWO_FACTOR_USER_FIELDS, AUTH_USER_CONFIG, AUTH_VERIFICATION_CONFIG, AuthManager, type AuthManagerOptions, AuthPlugin, type AuthPluginOptions, buildAdminPluginSchema, buildDeviceAuthorizationPluginSchema, buildJwtPluginSchema, buildOauthProviderPluginSchema, buildOidcProviderPluginSchema, buildOrganizationPluginSchema, buildTwoFactorPluginSchema, createObjectQLAdapter, createObjectQLAdapterFactory, resolveProtocolName };
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ import { AuthConfig, OidcProvidersConfig } from '@objectstack/spec/system';
3
3
  export { AuthConfig, AuthPluginConfig, AuthProviderConfig } from '@objectstack/spec/system';
4
4
  import * as better_auth from 'better-auth';
5
5
  import { Auth } from 'better-auth';
6
+ import { IEmailService } from '@objectstack/spec/contracts';
6
7
  import * as better_auth_adapters from 'better-auth/adapters';
7
8
  import { CleanedWhere } from 'better-auth/adapters';
8
9
 
@@ -21,6 +22,23 @@ interface AuthPluginOptions extends Partial<AuthConfig> {
21
22
  * @default '/api/v1/auth'
22
23
  */
23
24
  basePath?: string;
25
+ /**
26
+ * Override the datasource that owns the identity tables (sys_user,
27
+ * sys_session, …) when AuthPlugin's manifest is registered.
28
+ *
29
+ * Defaults to `'cloud'` (control-plane DB) so the historical
30
+ * single-tenant control-plane behaviour is preserved. Per-project
31
+ * kernels in objectos pass `'default'` so identity tables live in the
32
+ * project's own database — each project owns its own users.
33
+ */
34
+ manifestDatasource?: string;
35
+ /**
36
+ * Application-specific organization roles to register with Better-Auth's
37
+ * organization plugin so invitations to those roles aren't rejected with
38
+ * ROLE_NOT_FOUND. Forwarded as-is to AuthManager. See
39
+ * {@link AuthManagerOptions.additionalOrgRoles} for details.
40
+ */
41
+ additionalOrgRoles?: string[];
24
42
  }
25
43
  /**
26
44
  * Authentication Plugin
@@ -109,6 +127,42 @@ interface AuthManagerOptions extends Partial<AuthConfig> {
109
127
  * Each entry is passed to better-auth's genericOAuth plugin.
110
128
  */
111
129
  oidcProviders?: OidcProvidersConfig;
130
+ /**
131
+ * Application-specific organization roles to register with Better-Auth's
132
+ * organization plugin. Each name becomes a valid role for invitations and
133
+ * member assignments without going through Better-Auth's default
134
+ * `owner|admin|member` whitelist.
135
+ *
136
+ * The ObjectStack SecurityPlugin handles real RBAC enforcement by matching
137
+ * these role names against `permission` metadata (PermissionSets / Profiles),
138
+ * so Better-Auth only needs to accept them as opaque strings. Each role is
139
+ * registered with the minimum access-control privileges (equivalent to
140
+ * Better-Auth's `member` role) so it cannot inadvertently grant org-level
141
+ * admin capabilities.
142
+ *
143
+ * Typical source: the union of `permission` metadata names that have
144
+ * `isProfile: true`, collected from the loaded stack at CLI boot.
145
+ *
146
+ * @example ['sales_rep', 'sales_manager', 'service_agent']
147
+ */
148
+ additionalOrgRoles?: string[];
149
+ /**
150
+ * Optional outbound email service used by better-auth callbacks
151
+ * (`sendResetPassword`, `sendVerificationEmail`, `sendInvitationEmail`,
152
+ * `sendMagicLink`). When omitted, those callbacks degrade to logging
153
+ * the action URL — keeping flows usable in pilots / local dev — but
154
+ * production deployments SHOULD wire one via `setEmailService()`.
155
+ *
156
+ * Resolved lazily through {@link AuthManager.getEmailService}; safe
157
+ * to set after construction. AuthPlugin wires this from the kernel
158
+ * service registry on `kernel:ready`.
159
+ */
160
+ emailService?: IEmailService;
161
+ /**
162
+ * Display name used by built-in auth email templates (`{{appName}}`
163
+ * placeholder). Defaults to `'ObjectStack'` when omitted.
164
+ */
165
+ appName?: string;
112
166
  }
113
167
  /**
114
168
  * Authentication Manager
@@ -170,6 +224,20 @@ declare class AuthManager {
170
224
  * a warning is emitted.
171
225
  */
172
226
  setRuntimeBaseUrl(url: string): void;
227
+ /**
228
+ * Inject (or replace) the outbound email service used by better-auth
229
+ * callbacks. Safe to call after construction but BEFORE the first
230
+ * request hits the auth handler — callbacks read this via
231
+ * {@link getEmailService} when invoked.
232
+ *
233
+ * AuthPlugin calls this on `kernel:ready` once `ctx.getService('email')`
234
+ * resolves. For tests / serverless, callers may invoke directly.
235
+ */
236
+ setEmailService(email: IEmailService | undefined): void;
237
+ /** @internal Used by callback closures. */
238
+ private getEmailService;
239
+ /** @internal `{{appName}}` placeholder value for built-in templates. */
240
+ private getAppName;
173
241
  /**
174
242
  * Get the underlying better-auth instance
175
243
  * Useful for advanced use cases
@@ -544,6 +612,29 @@ declare const AUTH_TWO_FACTOR_SCHEMA: {
544
612
  declare const AUTH_TWO_FACTOR_USER_FIELDS: {
545
613
  readonly twoFactorEnabled: "two_factor_enabled";
546
614
  };
615
+ /**
616
+ * Admin plugin adds platform-level admin fields to the `user` model.
617
+ *
618
+ * | camelCase (better-auth) | snake_case (ObjectStack) |
619
+ * |:------------------------|:-------------------------|
620
+ * | banReason | ban_reason |
621
+ * | banExpires | ban_expires |
622
+ *
623
+ * `role` and `banned` already have matching snake_case names and are
624
+ * therefore omitted from this mapping (better-auth's database hooks
625
+ * read them by the auto-derived column names).
626
+ */
627
+ declare const AUTH_ADMIN_USER_FIELDS: {
628
+ readonly banReason: "ban_reason";
629
+ readonly banExpires: "ban_expires";
630
+ };
631
+ /**
632
+ * Admin plugin adds an `impersonatedBy` field to the session model
633
+ * recording the operator user id when an admin impersonates someone.
634
+ */
635
+ declare const AUTH_ADMIN_SESSION_FIELDS: {
636
+ readonly impersonatedBy: "impersonated_by";
637
+ };
547
638
  /**
548
639
  * `@better-auth/oauth-provider` plugin `oauthClient` model mapping.
549
640
  *
@@ -753,6 +844,26 @@ declare function buildTwoFactorPluginSchema(): {
753
844
  };
754
845
  };
755
846
  };
847
+ /**
848
+ * Builds the `schema` option for better-auth's `admin()` plugin.
849
+ *
850
+ * The admin plugin extends the user model with `role`/`banned`/`banReason`/
851
+ * `banExpires` and the session model with `impersonatedBy`. Only the
852
+ * snake_case-differing fields are mapped explicitly.
853
+ */
854
+ declare function buildAdminPluginSchema(): {
855
+ user: {
856
+ fields: {
857
+ readonly banReason: "ban_reason";
858
+ readonly banExpires: "ban_expires";
859
+ };
860
+ };
861
+ session: {
862
+ fields: {
863
+ readonly impersonatedBy: "impersonated_by";
864
+ };
865
+ };
866
+ };
756
867
  /**
757
868
  * Builds the `schema` option for better-auth's `organization()` plugin.
758
869
  *
@@ -952,4 +1063,4 @@ declare function buildDeviceAuthorizationPluginSchema(): {
952
1063
  };
953
1064
  };
954
1065
 
955
- export { AUTH_ACCOUNT_CONFIG, AUTH_DEVICE_CODE_SCHEMA, AUTH_INVITATION_SCHEMA, AUTH_JWKS_SCHEMA, AUTH_MEMBER_SCHEMA, AUTH_MODEL_TO_PROTOCOL, AUTH_OAUTH_ACCESS_TOKEN_SCHEMA, AUTH_OAUTH_APPLICATION_SCHEMA, AUTH_OAUTH_CLIENT_SCHEMA, AUTH_OAUTH_CONSENT_SCHEMA, AUTH_OAUTH_REFRESH_TOKEN_SCHEMA, AUTH_ORGANIZATION_SCHEMA, AUTH_ORG_SESSION_FIELDS, AUTH_SESSION_CONFIG, AUTH_TEAM_MEMBER_SCHEMA, AUTH_TEAM_SCHEMA, AUTH_TWO_FACTOR_SCHEMA, AUTH_TWO_FACTOR_USER_FIELDS, AUTH_USER_CONFIG, AUTH_VERIFICATION_CONFIG, AuthManager, type AuthManagerOptions, AuthPlugin, type AuthPluginOptions, buildDeviceAuthorizationPluginSchema, buildJwtPluginSchema, buildOauthProviderPluginSchema, buildOidcProviderPluginSchema, buildOrganizationPluginSchema, buildTwoFactorPluginSchema, createObjectQLAdapter, createObjectQLAdapterFactory, resolveProtocolName };
1066
+ export { AUTH_ACCOUNT_CONFIG, AUTH_ADMIN_SESSION_FIELDS, AUTH_ADMIN_USER_FIELDS, AUTH_DEVICE_CODE_SCHEMA, AUTH_INVITATION_SCHEMA, AUTH_JWKS_SCHEMA, AUTH_MEMBER_SCHEMA, AUTH_MODEL_TO_PROTOCOL, AUTH_OAUTH_ACCESS_TOKEN_SCHEMA, AUTH_OAUTH_APPLICATION_SCHEMA, AUTH_OAUTH_CLIENT_SCHEMA, AUTH_OAUTH_CONSENT_SCHEMA, AUTH_OAUTH_REFRESH_TOKEN_SCHEMA, AUTH_ORGANIZATION_SCHEMA, AUTH_ORG_SESSION_FIELDS, AUTH_SESSION_CONFIG, AUTH_TEAM_MEMBER_SCHEMA, AUTH_TEAM_SCHEMA, AUTH_TWO_FACTOR_SCHEMA, AUTH_TWO_FACTOR_USER_FIELDS, AUTH_USER_CONFIG, AUTH_VERIFICATION_CONFIG, AuthManager, type AuthManagerOptions, AuthPlugin, type AuthPluginOptions, buildAdminPluginSchema, buildDeviceAuthorizationPluginSchema, buildJwtPluginSchema, buildOauthProviderPluginSchema, buildOidcProviderPluginSchema, buildOrganizationPluginSchema, buildTwoFactorPluginSchema, createObjectQLAdapter, createObjectQLAdapterFactory, resolveProtocolName };