@banata-auth/convex 0.1.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/LICENSE +21 -0
- package/README.md +104 -0
- package/dist/auth-config.d.ts +22 -0
- package/dist/auth-config.d.ts.map +1 -0
- package/dist/auth-config.js +3 -0
- package/dist/auth-config.js.map +1 -0
- package/dist/auth.d.ts +462 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/component/adapter.d.ts +21 -0
- package/dist/component/adapter.d.ts.map +1 -0
- package/dist/component/adapter.js +3 -0
- package/dist/component/adapter.js.map +1 -0
- package/dist/component/schema.d.ts +1026 -0
- package/dist/component/schema.d.ts.map +1 -0
- package/dist/hooks.d.ts +25 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/http.d.ts +41 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +62 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9516 -0
- package/dist/index.js.map +1 -0
- package/dist/node.d.ts +389 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +9559 -0
- package/dist/node.js.map +1 -0
- package/dist/plugins/audit.d.ts +106 -0
- package/dist/plugins/audit.d.ts.map +1 -0
- package/dist/plugins/config.d.ts +83 -0
- package/dist/plugins/config.d.ts.map +1 -0
- package/dist/plugins/domains.d.ts +3 -0
- package/dist/plugins/domains.d.ts.map +1 -0
- package/dist/plugins/email-sender.d.ts +75 -0
- package/dist/plugins/email-sender.d.ts.map +1 -0
- package/dist/plugins/email-templates.d.ts +108 -0
- package/dist/plugins/email-templates.d.ts.map +1 -0
- package/dist/plugins/email.d.ts +82 -0
- package/dist/plugins/email.d.ts.map +1 -0
- package/dist/plugins/enterprise.d.ts +3 -0
- package/dist/plugins/enterprise.d.ts.map +1 -0
- package/dist/plugins/events.d.ts +40 -0
- package/dist/plugins/events.d.ts.map +1 -0
- package/dist/plugins/index.d.ts +18 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +9192 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/organization-rbac.d.ts +3 -0
- package/dist/plugins/organization-rbac.d.ts.map +1 -0
- package/dist/plugins/portal.d.ts +34 -0
- package/dist/plugins/portal.d.ts.map +1 -0
- package/dist/plugins/projects.d.ts +16 -0
- package/dist/plugins/projects.d.ts.map +1 -0
- package/dist/plugins/protection.d.ts +127 -0
- package/dist/plugins/protection.d.ts.map +1 -0
- package/dist/plugins/types.d.ts +508 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/user-management.d.ts +8 -0
- package/dist/plugins/user-management.d.ts.map +1 -0
- package/dist/plugins/vault.d.ts +68 -0
- package/dist/plugins/vault.d.ts.map +1 -0
- package/dist/plugins/webhook.d.ts +65 -0
- package/dist/plugins/webhook.d.ts.map +1 -0
- package/dist/triggers.d.ts +158 -0
- package/dist/triggers.d.ts.map +1 -0
- package/dist/triggers.js +36 -0
- package/dist/triggers.js.map +1 -0
- package/package.json +102 -0
- package/src/component/adapter.ts +21 -0
- package/src/component/convex.config.ts +15 -0
- package/src/component/schema.ts +916 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"organization-rbac.d.ts","sourceRoot":"","sources":["../../src/plugins/organization-rbac.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AA2YpD,wBAAgB,sBAAsB,IAAI,gBAAgB,CA05BzD"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Portal plugin for Banata Auth.
|
|
3
|
+
*
|
|
4
|
+
* Provides an Admin Portal link generation API that creates short-lived,
|
|
5
|
+
* scoped portal sessions for organization IT admins. Each portal link
|
|
6
|
+
* grants access to a specific intent (SSO, Directory Sync, Audit Logs, etc.)
|
|
7
|
+
* within an organization context.
|
|
8
|
+
*
|
|
9
|
+
* This mirrors WorkOS's Admin Portal feature, allowing you to generate
|
|
10
|
+
* a URL that redirects an org admin to a self-serve configuration page.
|
|
11
|
+
*
|
|
12
|
+
* @see {@link ../../../shared/src/types.ts} for the PortalSession SDK type
|
|
13
|
+
*/
|
|
14
|
+
import type { BetterAuthPlugin } from "better-auth";
|
|
15
|
+
/**
|
|
16
|
+
* Portal plugin for Banata Auth.
|
|
17
|
+
*
|
|
18
|
+
* Registers API endpoints under `/api/auth/banata/portal/*` that allow
|
|
19
|
+
* programmatic generation of short-lived admin portal links.
|
|
20
|
+
*
|
|
21
|
+
* @returns A Better Auth plugin descriptor
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* import { portalPlugin } from "./plugins/portal";
|
|
26
|
+
*
|
|
27
|
+
* const plugins = [
|
|
28
|
+
* portalPlugin(),
|
|
29
|
+
* // ... other plugins
|
|
30
|
+
* ];
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function portalPlugin(): BetterAuthPlugin;
|
|
34
|
+
//# sourceMappingURL=portal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portal.d.ts","sourceRoot":"","sources":["../../src/plugins/portal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAwEpD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,IAAI,gBAAgB,CA+K/C"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Banata Auth Projects Plugin
|
|
3
|
+
*
|
|
4
|
+
* Provides multi-project support.
|
|
5
|
+
* Each project is a fully isolated auth tenant with its own users, sessions,
|
|
6
|
+
* organizations, branding, email templates, API keys, webhooks, etc.
|
|
7
|
+
*/
|
|
8
|
+
import type { BetterAuthPlugin } from "better-auth";
|
|
9
|
+
export interface ProjectsPluginOptions {
|
|
10
|
+
/** Whether to auto-create a default project if none exist. Default: true */
|
|
11
|
+
autoCreateDefault?: boolean;
|
|
12
|
+
/** Default project name when auto-creating. Default: "Default Project" */
|
|
13
|
+
defaultProjectName?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function projectsPlugin(options?: ProjectsPluginOptions): BetterAuthPlugin;
|
|
16
|
+
//# sourceMappingURL=projects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/plugins/projects.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAkTpD,MAAM,WAAW,qBAAqB;IACrC,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,0EAA0E;IAC1E,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAID,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,gBAAgB,CA6PpF"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bot protection plugin for Banata Auth.
|
|
3
|
+
*
|
|
4
|
+
* Provides request-level bot detection and abuse prevention using
|
|
5
|
+
* Better Auth's `onRequest` hook. This plugin intercepts incoming
|
|
6
|
+
* requests BEFORE any auth processing occurs and can short-circuit
|
|
7
|
+
* with a 403 if a bot is detected.
|
|
8
|
+
*
|
|
9
|
+
* The plugin is provider-agnostic — it accepts a `verifyRequest`
|
|
10
|
+
* callback that consumers implement with their preferred bot detection
|
|
11
|
+
* service (Vercel BotID, Cloudflare Turnstile, hCaptcha, reCAPTCHA, etc.).
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { banataProtection } from "@banata-auth/convex/plugins";
|
|
16
|
+
*
|
|
17
|
+
* // The plugin is automatically included when you configure protection
|
|
18
|
+
* // in your BanataAuthConfig:
|
|
19
|
+
* const config: BanataAuthConfig = {
|
|
20
|
+
* protection: {
|
|
21
|
+
* enabled: true,
|
|
22
|
+
* protectedPaths: ["/sign-in", "/sign-up", "/forget-password", "/reset-password"],
|
|
23
|
+
* verifyRequest: async (request) => {
|
|
24
|
+
* // Implement your bot verification logic here
|
|
25
|
+
* return { isBot: false };
|
|
26
|
+
* },
|
|
27
|
+
* },
|
|
28
|
+
* };
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
import type { BetterAuthPlugin } from "better-auth";
|
|
32
|
+
/**
|
|
33
|
+
* Result of a bot verification check.
|
|
34
|
+
*/
|
|
35
|
+
export interface BotVerificationResult {
|
|
36
|
+
/** Whether the request was identified as coming from a bot. */
|
|
37
|
+
isBot: boolean;
|
|
38
|
+
/** Optional reason for the bot detection (for logging). */
|
|
39
|
+
reason?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Function that verifies whether a request is from a bot.
|
|
43
|
+
* Implement this with your bot detection provider of choice.
|
|
44
|
+
*
|
|
45
|
+
* @param request - The incoming HTTP request
|
|
46
|
+
* @returns Verification result indicating whether the request is from a bot
|
|
47
|
+
*/
|
|
48
|
+
export type BotVerifyFn = (request: Request) => Promise<BotVerificationResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Configuration for the bot protection plugin.
|
|
51
|
+
*/
|
|
52
|
+
export interface BanataProtectionOptions {
|
|
53
|
+
/**
|
|
54
|
+
* Whether bot protection is enabled.
|
|
55
|
+
* When false, all requests pass through without verification.
|
|
56
|
+
* @default true
|
|
57
|
+
*/
|
|
58
|
+
enabled?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Path prefixes to protect from bots.
|
|
61
|
+
* Only requests whose pathname starts with one of these prefixes
|
|
62
|
+
* will be verified. All other requests pass through.
|
|
63
|
+
*
|
|
64
|
+
* @default ["/sign-in", "/sign-up", "/forget-password", "/reset-password"]
|
|
65
|
+
*/
|
|
66
|
+
protectedPaths?: string[];
|
|
67
|
+
/**
|
|
68
|
+
* The bot verification function.
|
|
69
|
+
* Called for every request that matches a protected path.
|
|
70
|
+
* If not provided, requests pass through (useful for development).
|
|
71
|
+
*/
|
|
72
|
+
verifyRequest?: BotVerifyFn;
|
|
73
|
+
/**
|
|
74
|
+
* HTTP methods to check. By default only POST requests are verified
|
|
75
|
+
* since GET requests to auth endpoints are typically metadata/redirect
|
|
76
|
+
* flows, not credential submissions.
|
|
77
|
+
*
|
|
78
|
+
* @default ["POST"]
|
|
79
|
+
*/
|
|
80
|
+
protectedMethods?: string[];
|
|
81
|
+
/**
|
|
82
|
+
* Custom error message returned when a bot is detected.
|
|
83
|
+
* @default "Bot detected. Access denied."
|
|
84
|
+
*/
|
|
85
|
+
blockedMessage?: string;
|
|
86
|
+
/**
|
|
87
|
+
* Called when a bot is detected (for logging/analytics).
|
|
88
|
+
*/
|
|
89
|
+
onBotDetected?: (request: Request, result: BotVerificationResult) => void | Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Whether to fail open (allow request) when the verification
|
|
92
|
+
* function throws an error. This prevents legitimate users from
|
|
93
|
+
* being locked out if the bot detection service is unavailable.
|
|
94
|
+
*
|
|
95
|
+
* @default true
|
|
96
|
+
*/
|
|
97
|
+
failOpen?: boolean;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Bot protection plugin for Banata Auth.
|
|
101
|
+
*
|
|
102
|
+
* Uses Better Auth's `onRequest` hook to intercept requests before
|
|
103
|
+
* any auth processing. Protected paths are checked against the
|
|
104
|
+
* configured `verifyRequest` function.
|
|
105
|
+
*
|
|
106
|
+
* @param options - Protection configuration
|
|
107
|
+
* @returns A Better Auth plugin
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* import { banataProtection } from "@banata-auth/convex/plugins";
|
|
112
|
+
* import { checkBotId } from "botid/server";
|
|
113
|
+
*
|
|
114
|
+
* banataProtection({
|
|
115
|
+
* verifyRequest: async (request) => {
|
|
116
|
+
* try {
|
|
117
|
+
* const result = await checkBotId();
|
|
118
|
+
* return { isBot: result.isBot };
|
|
119
|
+
* } catch {
|
|
120
|
+
* return { isBot: false }; // fail open
|
|
121
|
+
* }
|
|
122
|
+
* },
|
|
123
|
+
* });
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
export declare function banataProtection(options?: BanataProtectionOptions): BetterAuthPlugin;
|
|
127
|
+
//# sourceMappingURL=protection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protection.d.ts","sourceRoot":"","sources":["../../src/plugins/protection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACrC,+DAA+D;IAC/D,KAAK,EAAE,OAAO,CAAC;IACf,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAE/E;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACvC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAE1B;;;;OAIG;IACH,aAAa,CAAC,EAAE,WAAW,CAAC;IAE5B;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE5B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,qBAAqB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1F;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAUD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B,GAAG,gBAAgB,CA4FxF"}
|
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared type definitions for Banata Auth plugins.
|
|
3
|
+
*
|
|
4
|
+
* These types provide type-safe interfaces for the Better Auth plugin system,
|
|
5
|
+
* replacing raw `any` usage throughout the plugin codebase.
|
|
6
|
+
*
|
|
7
|
+
* Better Auth's plugin system uses `better-call` endpoints under the hood.
|
|
8
|
+
* The handler context (`EndpointContext`) includes the full `AuthContext` which
|
|
9
|
+
* contains the database adapter, session info, and more.
|
|
10
|
+
*
|
|
11
|
+
* @see https://www.better-auth.com/docs/plugins/custom-plugin
|
|
12
|
+
*/
|
|
13
|
+
import type { BetterAuthOptions } from "better-auth";
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
/**
|
|
16
|
+
* Where clause for database queries.
|
|
17
|
+
* Matches Better Auth's Where type from @better-auth/core/dist/db/adapter.
|
|
18
|
+
*/
|
|
19
|
+
export interface WhereClause {
|
|
20
|
+
field: string;
|
|
21
|
+
value: string | number | boolean | string[] | number[] | Date | null;
|
|
22
|
+
operator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "in" | "not_in" | "contains" | "starts_with" | "ends_with";
|
|
23
|
+
connector?: "AND" | "OR";
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Sort specification for database queries.
|
|
27
|
+
*/
|
|
28
|
+
export interface SortBy {
|
|
29
|
+
field: string;
|
|
30
|
+
direction: "asc" | "desc";
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Typed subset of Better Auth's DBAdapter.
|
|
34
|
+
*
|
|
35
|
+
* This represents the adapter available on `ctx.context.adapter`.
|
|
36
|
+
* We use generic `Record<string, unknown>` for data instead of `any`.
|
|
37
|
+
*/
|
|
38
|
+
export interface PluginDBAdapter {
|
|
39
|
+
create: <T extends Record<string, unknown> = Record<string, unknown>>(data: {
|
|
40
|
+
model: string;
|
|
41
|
+
data: Record<string, unknown>;
|
|
42
|
+
select?: string[];
|
|
43
|
+
forceAllowId?: boolean;
|
|
44
|
+
}) => Promise<T>;
|
|
45
|
+
findOne: <T = Record<string, unknown>>(data: {
|
|
46
|
+
model: string;
|
|
47
|
+
where: WhereClause[];
|
|
48
|
+
select?: string[];
|
|
49
|
+
}) => Promise<T | null>;
|
|
50
|
+
findMany: <T = Record<string, unknown>>(data: {
|
|
51
|
+
model: string;
|
|
52
|
+
where?: WhereClause[];
|
|
53
|
+
limit?: number;
|
|
54
|
+
select?: string[];
|
|
55
|
+
sortBy?: SortBy;
|
|
56
|
+
offset?: number;
|
|
57
|
+
}) => Promise<T[]>;
|
|
58
|
+
update: <T = Record<string, unknown>>(data: {
|
|
59
|
+
model: string;
|
|
60
|
+
where: WhereClause[];
|
|
61
|
+
update: Record<string, unknown>;
|
|
62
|
+
}) => Promise<T | null>;
|
|
63
|
+
delete: (data: {
|
|
64
|
+
model: string;
|
|
65
|
+
where: WhereClause[];
|
|
66
|
+
}) => Promise<void>;
|
|
67
|
+
deleteMany: (data: {
|
|
68
|
+
model: string;
|
|
69
|
+
where: WhereClause[];
|
|
70
|
+
}) => Promise<number>;
|
|
71
|
+
count: (data: {
|
|
72
|
+
model: string;
|
|
73
|
+
where?: WhereClause[];
|
|
74
|
+
}) => Promise<number>;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Shape of a user record from the session context.
|
|
78
|
+
*/
|
|
79
|
+
export interface SessionUser {
|
|
80
|
+
id: string;
|
|
81
|
+
email: string;
|
|
82
|
+
name: string;
|
|
83
|
+
emailVerified: boolean;
|
|
84
|
+
image?: string | null;
|
|
85
|
+
role?: string;
|
|
86
|
+
banned?: boolean;
|
|
87
|
+
[key: string]: unknown;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Shape of a session record from the session context.
|
|
91
|
+
*/
|
|
92
|
+
export interface SessionRecord {
|
|
93
|
+
id: string;
|
|
94
|
+
userId: string;
|
|
95
|
+
token: string;
|
|
96
|
+
expiresAt: number | Date;
|
|
97
|
+
ipAddress?: string | null;
|
|
98
|
+
userAgent?: string | null;
|
|
99
|
+
activeOrganizationId?: string | null;
|
|
100
|
+
impersonatedBy?: string | null;
|
|
101
|
+
createdAt: number | Date;
|
|
102
|
+
updatedAt: number | Date;
|
|
103
|
+
[key: string]: unknown;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The AuthContext subset available on `ctx.context` in endpoint handlers.
|
|
107
|
+
*
|
|
108
|
+
* This is a narrowed version of Better Auth's full AuthContext, including
|
|
109
|
+
* only the fields typically used by custom plugins.
|
|
110
|
+
*/
|
|
111
|
+
export interface PluginAuthContext {
|
|
112
|
+
adapter: PluginDBAdapter;
|
|
113
|
+
session: {
|
|
114
|
+
session: SessionRecord;
|
|
115
|
+
user: SessionUser;
|
|
116
|
+
} | null;
|
|
117
|
+
options: BetterAuthOptions;
|
|
118
|
+
secret: string;
|
|
119
|
+
baseURL: string;
|
|
120
|
+
appName: string;
|
|
121
|
+
generateId: (options: {
|
|
122
|
+
model: string;
|
|
123
|
+
size?: number;
|
|
124
|
+
}) => string | false;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* The full endpoint handler context for plugin endpoints.
|
|
128
|
+
*
|
|
129
|
+
* This is the `ctx` parameter received by endpoint handlers registered
|
|
130
|
+
* in a BetterAuthPlugin's `endpoints` object.
|
|
131
|
+
*/
|
|
132
|
+
export interface PluginEndpointContext<TBody = Record<string, unknown>> {
|
|
133
|
+
/** Parsed and validated request body */
|
|
134
|
+
body: TBody;
|
|
135
|
+
/** Request query parameters */
|
|
136
|
+
query: Record<string, string | undefined>;
|
|
137
|
+
/** Request headers */
|
|
138
|
+
headers: Headers | undefined;
|
|
139
|
+
/** The auth context containing adapter, session, etc. */
|
|
140
|
+
context: PluginAuthContext;
|
|
141
|
+
/** Return a JSON response */
|
|
142
|
+
json: <R extends Record<string, unknown> | null>(data: R, options?: {
|
|
143
|
+
status?: number;
|
|
144
|
+
headers?: Record<string, string>;
|
|
145
|
+
} | Response) => Promise<R>;
|
|
146
|
+
/** Return an error response */
|
|
147
|
+
error: (status: number | string, body?: {
|
|
148
|
+
message?: string;
|
|
149
|
+
code?: string;
|
|
150
|
+
} & Record<string, unknown>, headers?: Record<string, string>) => Error;
|
|
151
|
+
/** The request path */
|
|
152
|
+
path: string;
|
|
153
|
+
/** The request object */
|
|
154
|
+
request: Request | undefined;
|
|
155
|
+
/** Get a request header */
|
|
156
|
+
getHeader: (key: string) => string | null;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Context passed to plugin hook matchers and handlers.
|
|
160
|
+
*/
|
|
161
|
+
export interface PluginHookContext {
|
|
162
|
+
path?: string;
|
|
163
|
+
context: PluginAuthContext & {
|
|
164
|
+
returned?: unknown;
|
|
165
|
+
responseHeaders?: Headers;
|
|
166
|
+
};
|
|
167
|
+
headers?: Headers;
|
|
168
|
+
body?: Record<string, unknown>;
|
|
169
|
+
query?: Record<string, string | undefined>;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Row shape for the `auditEvent` table.
|
|
173
|
+
*
|
|
174
|
+
* Index signature allows these types to satisfy Record<string, unknown>
|
|
175
|
+
* which is required by Better Auth's DBAdapter generic constraints.
|
|
176
|
+
*/
|
|
177
|
+
export interface AuditEventRow extends Record<string, unknown> {
|
|
178
|
+
id: string;
|
|
179
|
+
action: string;
|
|
180
|
+
version: number | null;
|
|
181
|
+
actorType: string;
|
|
182
|
+
actorId: string;
|
|
183
|
+
actorName: string | null;
|
|
184
|
+
actorEmail: string | null;
|
|
185
|
+
/** JSON-serialized Record<string, string> */
|
|
186
|
+
actorMetadata: string | null;
|
|
187
|
+
targets: string | null;
|
|
188
|
+
organizationId: string | null;
|
|
189
|
+
ipAddress: string | null;
|
|
190
|
+
userAgent: string | null;
|
|
191
|
+
requestId: string | null;
|
|
192
|
+
changes: string | null;
|
|
193
|
+
idempotencyKey: string | null;
|
|
194
|
+
/** JSON-serialized Record<string, string> */
|
|
195
|
+
metadata: string | null;
|
|
196
|
+
occurredAt: number;
|
|
197
|
+
createdAt: number;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Row shape for the `webhookEndpoint` table.
|
|
201
|
+
*/
|
|
202
|
+
export interface WebhookEndpointRow extends Record<string, unknown> {
|
|
203
|
+
id: string;
|
|
204
|
+
url: string;
|
|
205
|
+
secret: string;
|
|
206
|
+
eventTypes: string | null;
|
|
207
|
+
enabled: boolean;
|
|
208
|
+
successCount: number | null;
|
|
209
|
+
failureCount: number | null;
|
|
210
|
+
consecutiveFailures: number | null;
|
|
211
|
+
lastDeliveryAt: number | null;
|
|
212
|
+
lastDeliveryStatus: string | null;
|
|
213
|
+
createdAt: number;
|
|
214
|
+
updatedAt: number;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Row shape for the `webhookDelivery` table.
|
|
218
|
+
*/
|
|
219
|
+
export interface WebhookDeliveryRow extends Record<string, unknown> {
|
|
220
|
+
id: string;
|
|
221
|
+
endpointId: string;
|
|
222
|
+
eventType: string;
|
|
223
|
+
payload: string;
|
|
224
|
+
attempt: number;
|
|
225
|
+
maxAttempts: number;
|
|
226
|
+
status: "pending" | "success" | "failed" | "retrying";
|
|
227
|
+
httpStatus: number | null;
|
|
228
|
+
responseBody: string | null;
|
|
229
|
+
errorMessage: string | null;
|
|
230
|
+
nextRetryAt: number | null;
|
|
231
|
+
deliveredAt: number | null;
|
|
232
|
+
createdAt: number;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Row shape for the `roleDefinition` table.
|
|
236
|
+
*/
|
|
237
|
+
export interface RoleDefinitionRow extends Record<string, unknown> {
|
|
238
|
+
id: string;
|
|
239
|
+
name: string;
|
|
240
|
+
slug: string;
|
|
241
|
+
description: string | null;
|
|
242
|
+
permissions: string | null;
|
|
243
|
+
isDefault: boolean | null;
|
|
244
|
+
createdAt: number;
|
|
245
|
+
updatedAt: number;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Row shape for the `permissionDefinition` table.
|
|
249
|
+
*/
|
|
250
|
+
export interface PermissionDefinitionRow extends Record<string, unknown> {
|
|
251
|
+
id: string;
|
|
252
|
+
name: string;
|
|
253
|
+
slug: string;
|
|
254
|
+
description: string | null;
|
|
255
|
+
createdAt: number;
|
|
256
|
+
updatedAt: number;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Row shape for the `brandingConfig` table.
|
|
260
|
+
*/
|
|
261
|
+
export interface BrandingConfigRow extends Record<string, unknown> {
|
|
262
|
+
id: string;
|
|
263
|
+
primaryColor: string | null;
|
|
264
|
+
bgColor: string | null;
|
|
265
|
+
borderRadius: number | null;
|
|
266
|
+
darkMode: boolean | null;
|
|
267
|
+
customCss: string | null;
|
|
268
|
+
font: string | null;
|
|
269
|
+
logoUrl: string | null;
|
|
270
|
+
createdAt: number;
|
|
271
|
+
updatedAt: number;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Row shape for the `emailTemplate` table.
|
|
275
|
+
*/
|
|
276
|
+
export interface EmailTemplateRow extends Record<string, unknown> {
|
|
277
|
+
id: string;
|
|
278
|
+
name: string;
|
|
279
|
+
slug: string;
|
|
280
|
+
subject: string;
|
|
281
|
+
previewText: string | null;
|
|
282
|
+
category: string;
|
|
283
|
+
description: string | null;
|
|
284
|
+
/** JSON-serialized EmailBlock[] array. */
|
|
285
|
+
blocksJson: string;
|
|
286
|
+
/** JSON-serialized EmailTemplateVariable[] array. */
|
|
287
|
+
variablesJson: string | null;
|
|
288
|
+
builtIn: boolean | null;
|
|
289
|
+
builtInType: string | null;
|
|
290
|
+
createdAt: number;
|
|
291
|
+
updatedAt: number;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Row shape for the `emailConfig` table.
|
|
295
|
+
*/
|
|
296
|
+
export interface EmailConfigRow extends Record<string, unknown> {
|
|
297
|
+
id: string;
|
|
298
|
+
emailType: string;
|
|
299
|
+
name: string;
|
|
300
|
+
description: string | null;
|
|
301
|
+
enabled: boolean;
|
|
302
|
+
category: string;
|
|
303
|
+
createdAt: number;
|
|
304
|
+
updatedAt: number;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Row shape for the `dashboardConfig` table.
|
|
308
|
+
* Singleton row pattern: at most one row exists.
|
|
309
|
+
* Stores JSON-serialized partial dashboard config overrides.
|
|
310
|
+
*/
|
|
311
|
+
export interface DashboardConfigRow extends Record<string, unknown> {
|
|
312
|
+
id: string;
|
|
313
|
+
/** JSON-serialized partial dashboard config overrides */
|
|
314
|
+
configJson: string;
|
|
315
|
+
createdAt: number;
|
|
316
|
+
updatedAt: number;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Row shape for the `domainConfig` table.
|
|
320
|
+
*/
|
|
321
|
+
export interface DomainConfigRow extends Record<string, unknown> {
|
|
322
|
+
id: string;
|
|
323
|
+
domainKey: string;
|
|
324
|
+
title: string;
|
|
325
|
+
description: string | null;
|
|
326
|
+
value: string;
|
|
327
|
+
isDefault: boolean | null;
|
|
328
|
+
createdAt: number;
|
|
329
|
+
updatedAt: number;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Row shape for the `redirectConfig` table.
|
|
333
|
+
* Singleton row with JSON-serialized redirect settings.
|
|
334
|
+
*/
|
|
335
|
+
export interface RedirectConfigRow extends Record<string, unknown> {
|
|
336
|
+
id: string;
|
|
337
|
+
configJson: string;
|
|
338
|
+
createdAt: number;
|
|
339
|
+
updatedAt: number;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Row shape for the `actionConfig` table.
|
|
343
|
+
*/
|
|
344
|
+
export interface ActionConfigRow extends Record<string, unknown> {
|
|
345
|
+
id: string;
|
|
346
|
+
name: string;
|
|
347
|
+
description: string | null;
|
|
348
|
+
triggerEvent: string;
|
|
349
|
+
webhookUrl: string;
|
|
350
|
+
createdAt: number;
|
|
351
|
+
updatedAt: number;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Row shape for the `radarConfig` table.
|
|
355
|
+
* Singleton row with JSON-serialized radar/bot protection settings.
|
|
356
|
+
*/
|
|
357
|
+
export interface RadarConfigRow extends Record<string, unknown> {
|
|
358
|
+
id: string;
|
|
359
|
+
configJson: string;
|
|
360
|
+
createdAt: number;
|
|
361
|
+
updatedAt: number;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Row shape for the `emailProviderConfig` table.
|
|
365
|
+
* Singleton row with JSON-serialized email provider settings.
|
|
366
|
+
*/
|
|
367
|
+
export interface EmailProviderConfigRow extends Record<string, unknown> {
|
|
368
|
+
id: string;
|
|
369
|
+
configJson: string;
|
|
370
|
+
createdAt: number;
|
|
371
|
+
updatedAt: number;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Row shape for the `resourceType` table.
|
|
375
|
+
*/
|
|
376
|
+
export interface ResourceTypeRow extends Record<string, unknown> {
|
|
377
|
+
id: string;
|
|
378
|
+
name: string;
|
|
379
|
+
slug: string;
|
|
380
|
+
description: string | null;
|
|
381
|
+
createdAt: number;
|
|
382
|
+
updatedAt: number;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Row shape for the `addonConfig` table.
|
|
386
|
+
* Singleton row with JSON-serialized addon states.
|
|
387
|
+
*/
|
|
388
|
+
export interface AddonConfigRow extends Record<string, unknown> {
|
|
389
|
+
id: string;
|
|
390
|
+
configJson: string;
|
|
391
|
+
createdAt: number;
|
|
392
|
+
updatedAt: number;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Row shape for the `projectConfig` table.
|
|
396
|
+
* One row per project with JSON-serialized project settings.
|
|
397
|
+
*/
|
|
398
|
+
export interface ProjectConfigRow extends Record<string, unknown> {
|
|
399
|
+
id: string;
|
|
400
|
+
configJson: string;
|
|
401
|
+
projectId?: string;
|
|
402
|
+
createdAt: number;
|
|
403
|
+
updatedAt: number;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Row shape for the `project` table.
|
|
407
|
+
* Each project is a fully isolated auth tenant.
|
|
408
|
+
*/
|
|
409
|
+
export interface ProjectRow extends Record<string, unknown> {
|
|
410
|
+
id: string;
|
|
411
|
+
name: string;
|
|
412
|
+
slug: string;
|
|
413
|
+
description?: string;
|
|
414
|
+
logoUrl?: string;
|
|
415
|
+
ownerId: string;
|
|
416
|
+
createdAt: number;
|
|
417
|
+
updatedAt: number;
|
|
418
|
+
}
|
|
419
|
+
export declare function parseRoleSlugs(value: string | string[] | null | undefined): string[];
|
|
420
|
+
export declare function isGlobalAdminRole(role: string | null | undefined): boolean;
|
|
421
|
+
export declare function isGlobalAdminUser(user: Pick<SessionUser, "role"> | null | undefined): boolean;
|
|
422
|
+
/**
|
|
423
|
+
* Verify that the current request has an authenticated session.
|
|
424
|
+
*
|
|
425
|
+
* This MUST be called at the top of every custom plugin endpoint
|
|
426
|
+
* that performs administrative operations (webhook CRUD, audit log
|
|
427
|
+
* management, roles/permissions CRUD, branding, email config, etc.).
|
|
428
|
+
*
|
|
429
|
+
* The function uses a loose type signature to remain compatible with
|
|
430
|
+
* Better Auth's `EndpointContext` which uses a narrower union type
|
|
431
|
+
* for error status codes (e.g. `"UNAUTHORIZED" | "FORBIDDEN" | ...`)
|
|
432
|
+
* rather than `string | number`.
|
|
433
|
+
*
|
|
434
|
+
* @param ctx - The endpoint handler context from Better Auth
|
|
435
|
+
* @throws Error with status "UNAUTHORIZED" if not authenticated
|
|
436
|
+
*/
|
|
437
|
+
export declare function requireAuthenticated(ctx: any): {
|
|
438
|
+
session: SessionRecord;
|
|
439
|
+
user: SessionUser;
|
|
440
|
+
};
|
|
441
|
+
/**
|
|
442
|
+
* @deprecated Use `requireAuthenticated` or `requireGlobalAdmin` instead.
|
|
443
|
+
*/
|
|
444
|
+
export declare function requireAdmin(ctx: any): {
|
|
445
|
+
session: SessionRecord;
|
|
446
|
+
user: SessionUser;
|
|
447
|
+
};
|
|
448
|
+
export declare function requireGlobalAdmin(ctx: any): {
|
|
449
|
+
session: SessionRecord;
|
|
450
|
+
user: SessionUser;
|
|
451
|
+
};
|
|
452
|
+
export declare function getRolePermissions(db: PluginDBAdapter, params: {
|
|
453
|
+
projectId?: string;
|
|
454
|
+
roleSlugs: string[];
|
|
455
|
+
}): Promise<Set<string>>;
|
|
456
|
+
/**
|
|
457
|
+
* Resolve the effective permission slugs for a user in a project.
|
|
458
|
+
*
|
|
459
|
+
* Permission sources:
|
|
460
|
+
* 1) Global Better Auth admin role (`user.role`)
|
|
461
|
+
* 2) Project ownership (`project.ownerId`)
|
|
462
|
+
* 3) Organization membership roles in the project (`member.role`)
|
|
463
|
+
*/
|
|
464
|
+
export declare function getEffectiveProjectPermissions(db: PluginDBAdapter, params: {
|
|
465
|
+
userId: string;
|
|
466
|
+
projectId?: string;
|
|
467
|
+
}): Promise<Set<string>>;
|
|
468
|
+
/**
|
|
469
|
+
* Throws FORBIDDEN unless the current user has the given permission in project scope.
|
|
470
|
+
*/
|
|
471
|
+
export declare function requireProjectPermission(ctx: any, params: {
|
|
472
|
+
db: PluginDBAdapter;
|
|
473
|
+
permission: string;
|
|
474
|
+
projectId?: string;
|
|
475
|
+
}): Promise<void>;
|
|
476
|
+
/**
|
|
477
|
+
* Zod schema partial for project-scoped endpoints.
|
|
478
|
+
* Add `.merge(projectScopeSchema)` to any endpoint body schema that
|
|
479
|
+
* should accept an optional projectId.
|
|
480
|
+
*/
|
|
481
|
+
export declare const projectScopeSchema: z.ZodObject<{
|
|
482
|
+
projectId: z.ZodOptional<z.ZodString>;
|
|
483
|
+
}, "strip", z.ZodTypeAny, {
|
|
484
|
+
projectId?: string | undefined;
|
|
485
|
+
}, {
|
|
486
|
+
projectId?: string | undefined;
|
|
487
|
+
}>;
|
|
488
|
+
/**
|
|
489
|
+
* Extract projectId from a parsed body and return scope helpers.
|
|
490
|
+
*
|
|
491
|
+
* **Strict by default**: throws if `projectId` is missing.
|
|
492
|
+
* All project-scoped data MUST be isolated — returning empty filters
|
|
493
|
+
* would silently leak data across projects.
|
|
494
|
+
*
|
|
495
|
+
* Pass `{ optional: true }` only for endpoints that genuinely operate
|
|
496
|
+
* across all projects (e.g. project list, ensure-default).
|
|
497
|
+
*/
|
|
498
|
+
export declare function getProjectScope(body: Record<string, unknown>, opts?: {
|
|
499
|
+
optional?: boolean;
|
|
500
|
+
}): {
|
|
501
|
+
/** Where clause filter for findMany/findOne/update/delete. */
|
|
502
|
+
where: WhereClause[];
|
|
503
|
+
/** Data fields to include in create. */
|
|
504
|
+
data: Record<string, string>;
|
|
505
|
+
/** The resolved projectId (always present when strict). */
|
|
506
|
+
projectId: string | undefined;
|
|
507
|
+
};
|
|
508
|
+
//# sourceMappingURL=types.d.ts.map
|