@contentgrowth/content-auth 0.0.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/README.md +255 -0
- package/dist/backend/index.d.ts +1077 -0
- package/dist/backend/index.js +15 -0
- package/dist/chunk-526JE62U.js +142 -0
- package/dist/chunk-NKDKDBM2.js +17 -0
- package/dist/chunk-R5U7XKVJ.js +16 -0
- package/dist/chunk-VX6RJ5XJ.js +372 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +105 -0
- package/dist/frontend/client.d.ts +3161 -0
- package/dist/frontend/client.js +9 -0
- package/dist/frontend/index.d.ts +38 -0
- package/dist/frontend/index.js +19 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +31 -0
- package/dist/styles.css +264 -0
- package/package.json +72 -0
- package/schema/auth.sql +115 -0
- package/schema/schema.template.ts +167 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { authClient } from './client.js';
|
|
3
|
+
export { createClient } from './client.js';
|
|
4
|
+
import 'nanostores';
|
|
5
|
+
import '@better-fetch/fetch';
|
|
6
|
+
import 'better-auth';
|
|
7
|
+
import 'better-auth/plugins';
|
|
8
|
+
|
|
9
|
+
interface AuthFormProps {
|
|
10
|
+
view?: 'signin' | 'signup';
|
|
11
|
+
client?: typeof authClient;
|
|
12
|
+
onSuccess?: () => void;
|
|
13
|
+
className?: string;
|
|
14
|
+
socialProviders?: string[];
|
|
15
|
+
socialLayout?: 'row' | 'column';
|
|
16
|
+
title?: React.ReactNode;
|
|
17
|
+
width?: 'default' | 'compact' | 'wide';
|
|
18
|
+
layout?: 'default' | 'split';
|
|
19
|
+
socialPosition?: 'top' | 'bottom';
|
|
20
|
+
onSwitchMode?: () => void;
|
|
21
|
+
}
|
|
22
|
+
declare const AuthForm: React.FC<AuthFormProps>;
|
|
23
|
+
|
|
24
|
+
interface BaseOrgProps {
|
|
25
|
+
client?: typeof authClient;
|
|
26
|
+
className?: string;
|
|
27
|
+
onSuccess?: (data?: any) => void;
|
|
28
|
+
onError?: (error: string) => void;
|
|
29
|
+
}
|
|
30
|
+
declare const CreateOrganizationForm: React.FC<BaseOrgProps>;
|
|
31
|
+
declare const OrganizationSwitcher: React.FC<BaseOrgProps & {
|
|
32
|
+
currentOrgId?: string;
|
|
33
|
+
}>;
|
|
34
|
+
declare const InviteMemberForm: React.FC<BaseOrgProps & {
|
|
35
|
+
organizationId?: string;
|
|
36
|
+
}>;
|
|
37
|
+
|
|
38
|
+
export { AuthForm, CreateOrganizationForm, InviteMemberForm, OrganizationSwitcher, authClient };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AuthForm,
|
|
3
|
+
CreateOrganizationForm,
|
|
4
|
+
InviteMemberForm,
|
|
5
|
+
OrganizationSwitcher
|
|
6
|
+
} from "../chunk-VX6RJ5XJ.js";
|
|
7
|
+
import {
|
|
8
|
+
authClient,
|
|
9
|
+
createClient
|
|
10
|
+
} from "../chunk-NKDKDBM2.js";
|
|
11
|
+
import "../chunk-R5U7XKVJ.js";
|
|
12
|
+
export {
|
|
13
|
+
AuthForm,
|
|
14
|
+
CreateOrganizationForm,
|
|
15
|
+
InviteMemberForm,
|
|
16
|
+
OrganizationSwitcher,
|
|
17
|
+
authClient,
|
|
18
|
+
createClient
|
|
19
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { AuthConfig, authMiddleware, createAuth, createAuthApp, schema } from './backend/index.js';
|
|
2
|
+
export { AuthForm, CreateOrganizationForm, InviteMemberForm, OrganizationSwitcher } from './frontend/index.js';
|
|
3
|
+
export { authClient, createClient } from './frontend/client.js';
|
|
4
|
+
export * from 'better-auth';
|
|
5
|
+
export { Hono } from 'hono';
|
|
6
|
+
import 'hono/types';
|
|
7
|
+
import '@cloudflare/workers-types';
|
|
8
|
+
import 'drizzle-orm/sqlite-core';
|
|
9
|
+
import 'react';
|
|
10
|
+
import 'nanostores';
|
|
11
|
+
import '@better-fetch/fetch';
|
|
12
|
+
import 'better-auth/plugins';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Hono,
|
|
3
|
+
authMiddleware,
|
|
4
|
+
createAuth,
|
|
5
|
+
createAuthApp,
|
|
6
|
+
schema_exports
|
|
7
|
+
} from "./chunk-526JE62U.js";
|
|
8
|
+
import {
|
|
9
|
+
AuthForm,
|
|
10
|
+
CreateOrganizationForm,
|
|
11
|
+
InviteMemberForm,
|
|
12
|
+
OrganizationSwitcher
|
|
13
|
+
} from "./chunk-VX6RJ5XJ.js";
|
|
14
|
+
import {
|
|
15
|
+
authClient,
|
|
16
|
+
createClient
|
|
17
|
+
} from "./chunk-NKDKDBM2.js";
|
|
18
|
+
import "./chunk-R5U7XKVJ.js";
|
|
19
|
+
export {
|
|
20
|
+
AuthForm,
|
|
21
|
+
CreateOrganizationForm,
|
|
22
|
+
Hono,
|
|
23
|
+
InviteMemberForm,
|
|
24
|
+
OrganizationSwitcher,
|
|
25
|
+
authClient,
|
|
26
|
+
authMiddleware,
|
|
27
|
+
createAuth,
|
|
28
|
+
createAuthApp,
|
|
29
|
+
createClient,
|
|
30
|
+
schema_exports as schema
|
|
31
|
+
};
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
.ca-container {
|
|
2
|
+
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
|
3
|
+
width: 100%;
|
|
4
|
+
max-width: 420px;
|
|
5
|
+
margin: 0 auto;
|
|
6
|
+
padding: 2.5rem;
|
|
7
|
+
border-radius: 16px;
|
|
8
|
+
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
|
9
|
+
background-color: white;
|
|
10
|
+
border: 1px solid #f3f4f6;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.ca-title {
|
|
14
|
+
font-size: 1.75rem;
|
|
15
|
+
font-weight: 700;
|
|
16
|
+
text-align: center;
|
|
17
|
+
margin-bottom: 2rem;
|
|
18
|
+
color: #111827;
|
|
19
|
+
letter-spacing: -0.025em;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.ca-form {
|
|
23
|
+
display: flex;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
gap: 1.25rem;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.ca-input-group {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-direction: column;
|
|
31
|
+
gap: 0.5rem;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.ca-label {
|
|
35
|
+
font-size: 0.875rem;
|
|
36
|
+
font-weight: 500;
|
|
37
|
+
color: #374151;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.ca-input {
|
|
41
|
+
padding: 0.75rem 1rem;
|
|
42
|
+
border-radius: 8px;
|
|
43
|
+
border: 1px solid #e5e7eb;
|
|
44
|
+
font-size: 0.95rem;
|
|
45
|
+
transition: all 0.2s ease;
|
|
46
|
+
background-color: #f9fafb;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.ca-input:focus {
|
|
50
|
+
outline: none;
|
|
51
|
+
border-color: #3b82f6;
|
|
52
|
+
background-color: white;
|
|
53
|
+
box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.ca-button {
|
|
57
|
+
display: inline-flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
justify-content: center;
|
|
60
|
+
padding: 0.75rem 1.5rem;
|
|
61
|
+
border-radius: 8px;
|
|
62
|
+
border: 1px solid transparent;
|
|
63
|
+
font-weight: 500;
|
|
64
|
+
font-size: 0.95rem;
|
|
65
|
+
cursor: pointer;
|
|
66
|
+
transition: all 0.2s ease;
|
|
67
|
+
gap: 0.5rem;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.ca-button-primary,
|
|
71
|
+
button[type="submit"] {
|
|
72
|
+
background-color: #111827;
|
|
73
|
+
color: white;
|
|
74
|
+
border: 1px solid #111827;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
button[type="submit"]:hover {
|
|
78
|
+
background-color: #1f2937;
|
|
79
|
+
border-color: #1f2937;
|
|
80
|
+
transform: translateY(-1px);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.ca-button-submit:disabled,
|
|
84
|
+
button[type="submit"]:disabled {
|
|
85
|
+
background-color: #9ca3af;
|
|
86
|
+
border-color: #9ca3af;
|
|
87
|
+
cursor: not-allowed;
|
|
88
|
+
transform: none;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* Social Buttons */
|
|
92
|
+
.ca-social-grid {
|
|
93
|
+
display: grid;
|
|
94
|
+
grid-template-columns: 1fr 1fr;
|
|
95
|
+
gap: 1rem;
|
|
96
|
+
margin-bottom: 1.5rem;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.ca-button-social {
|
|
100
|
+
background-color: white;
|
|
101
|
+
color: #374151;
|
|
102
|
+
border: 1px solid #e5e7eb;
|
|
103
|
+
padding: 0.625rem 1rem;
|
|
104
|
+
font-weight: 500;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.ca-button-social:hover {
|
|
108
|
+
background-color: #f9fafb;
|
|
109
|
+
border-color: #d1d5db;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.ca-icon {
|
|
113
|
+
flex-shrink: 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* Divider */
|
|
117
|
+
.ca-divider {
|
|
118
|
+
position: relative;
|
|
119
|
+
text-align: center;
|
|
120
|
+
margin: 1.5rem 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.ca-divider::before {
|
|
124
|
+
content: "";
|
|
125
|
+
position: absolute;
|
|
126
|
+
top: 50%;
|
|
127
|
+
left: 0;
|
|
128
|
+
right: 0;
|
|
129
|
+
height: 1px;
|
|
130
|
+
background-color: #e5e7eb;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.ca-divider-text {
|
|
134
|
+
position: relative;
|
|
135
|
+
background-color: white;
|
|
136
|
+
padding: 0 0.75rem;
|
|
137
|
+
color: #6b7280;
|
|
138
|
+
font-size: 0.875rem;
|
|
139
|
+
font-weight: 400;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.ca-social-header {
|
|
143
|
+
font-size: 0.875rem;
|
|
144
|
+
font-weight: 500;
|
|
145
|
+
color: #374151;
|
|
146
|
+
text-align: center;
|
|
147
|
+
margin-bottom: 1rem;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.ca-footer {
|
|
151
|
+
margin-top: 2rem;
|
|
152
|
+
text-align: center;
|
|
153
|
+
font-size: 0.875rem;
|
|
154
|
+
color: #6b7280;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.ca-link {
|
|
158
|
+
color: #2563eb;
|
|
159
|
+
text-decoration: none;
|
|
160
|
+
cursor: pointer;
|
|
161
|
+
background: none;
|
|
162
|
+
border: none;
|
|
163
|
+
padding: 0;
|
|
164
|
+
font: inherit;
|
|
165
|
+
font-weight: 500;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.ca-link:hover {
|
|
169
|
+
text-decoration: underline;
|
|
170
|
+
color: #1d4ed8;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.ca-error {
|
|
174
|
+
background-color: #fef2f2;
|
|
175
|
+
color: #ef4444;
|
|
176
|
+
font-size: 0.875rem;
|
|
177
|
+
padding: 0.75rem;
|
|
178
|
+
border-radius: 6px;
|
|
179
|
+
border: 1px solid #fee2e2;
|
|
180
|
+
text-align: center;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* New Layout Classes */
|
|
184
|
+
.ca-social-column {
|
|
185
|
+
display: flex;
|
|
186
|
+
flex-direction: column;
|
|
187
|
+
gap: 0.75rem;
|
|
188
|
+
margin-bottom: 1.5rem;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.ca-container-wide {
|
|
192
|
+
max-width: 600px;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/* Split Layout */
|
|
196
|
+
.ca-split-body {
|
|
197
|
+
display: flex;
|
|
198
|
+
flex-direction: column;
|
|
199
|
+
gap: 1.5rem;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
@media (min-width: 640px) {
|
|
203
|
+
.ca-layout-split .ca-split-body {
|
|
204
|
+
flex-direction: row;
|
|
205
|
+
align-items: stretch;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.ca-layout-split.ca-container {
|
|
209
|
+
/* base styles, width controlled by utility classes */
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/* Width Variants */
|
|
213
|
+
.ca-layout-split.ca-width-compact {
|
|
214
|
+
max-width: 640px !important;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.ca-layout-split.ca-width-default {
|
|
218
|
+
max-width: 768px !important;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.ca-layout-split.ca-width-wide {
|
|
222
|
+
max-width: 1000px !important;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.ca-split-main {
|
|
226
|
+
flex: 2;
|
|
227
|
+
min-width: 0;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.ca-split-divider {
|
|
231
|
+
display: flex;
|
|
232
|
+
flex-direction: column;
|
|
233
|
+
align-items: center;
|
|
234
|
+
justify-content: center;
|
|
235
|
+
padding: 0 1.5rem;
|
|
236
|
+
position: relative;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.ca-split-divider::before {
|
|
240
|
+
content: "";
|
|
241
|
+
position: absolute;
|
|
242
|
+
top: 10%;
|
|
243
|
+
bottom: 10%;
|
|
244
|
+
left: 50%;
|
|
245
|
+
width: 1px;
|
|
246
|
+
background-color: #e5e7eb;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.ca-split-divider-text {
|
|
250
|
+
background-color: white;
|
|
251
|
+
padding: 0.5rem 0;
|
|
252
|
+
color: #6b7280;
|
|
253
|
+
font-size: 0.875rem;
|
|
254
|
+
z-index: 1;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.ca-split-social {
|
|
258
|
+
flex: 1;
|
|
259
|
+
flex-shrink: 0;
|
|
260
|
+
display: flex;
|
|
261
|
+
flex-direction: column;
|
|
262
|
+
justify-content: center;
|
|
263
|
+
}
|
|
264
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@contentgrowth/content-auth",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Better Auth wrapper with UI components for Cloudflare Workers & Pages",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"bin": {
|
|
10
|
+
"content-auth": "./dist/cli.js"
|
|
11
|
+
},
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./backend": {
|
|
18
|
+
"types": "./dist/backend/index.d.ts",
|
|
19
|
+
"import": "./dist/backend/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./frontend": {
|
|
22
|
+
"types": "./dist/frontend/index.d.ts",
|
|
23
|
+
"import": "./dist/frontend/index.js"
|
|
24
|
+
},
|
|
25
|
+
"./client": {
|
|
26
|
+
"types": "./dist/frontend/client.d.ts",
|
|
27
|
+
"import": "./dist/frontend/client.js"
|
|
28
|
+
},
|
|
29
|
+
"./styles.css": "./dist/styles.css"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"schema",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsup && cp src/styles.css dist/styles.css",
|
|
39
|
+
"dev": "tsup --watch",
|
|
40
|
+
"prepublishOnly": "npm run build"
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"auth",
|
|
44
|
+
"better-auth",
|
|
45
|
+
"cloudflare",
|
|
46
|
+
"workers",
|
|
47
|
+
"pages",
|
|
48
|
+
"react"
|
|
49
|
+
],
|
|
50
|
+
"author": "Content Growth",
|
|
51
|
+
"license": "MIT",
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"react": "^18.0.0",
|
|
54
|
+
"react-dom": "^18.0.0"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"better-auth": "^1.0.0",
|
|
58
|
+
"cac": "^6.0.0",
|
|
59
|
+
"drizzle-orm": "^0.45.0",
|
|
60
|
+
"hono": "^4.0.0"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@cloudflare/workers-types": "^4.20240101.0",
|
|
64
|
+
"@types/node": "^20.0.0",
|
|
65
|
+
"@types/react": "^18.0.0",
|
|
66
|
+
"@types/react-dom": "^18.0.0",
|
|
67
|
+
"react": "^18.0.0",
|
|
68
|
+
"react-dom": "^18.0.0",
|
|
69
|
+
"tsup": "^8.0.0",
|
|
70
|
+
"typescript": "^5.0.0"
|
|
71
|
+
}
|
|
72
|
+
}
|
package/schema/auth.sql
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
-- ============================================
|
|
2
|
+
-- @contentgrowth/content-auth - Database Schema Template
|
|
3
|
+
-- ============================================
|
|
4
|
+
--
|
|
5
|
+
-- USAGE:
|
|
6
|
+
-- 1. Copy this file to your project's migrations folder
|
|
7
|
+
-- 2. Add your application-specific tables after the auth tables
|
|
8
|
+
-- 3. Run migrations (e.g., wrangler d1 migrations apply DB --local)
|
|
9
|
+
--
|
|
10
|
+
-- EXTENDING TABLES:
|
|
11
|
+
-- You can add extra columns to any table for your business needs.
|
|
12
|
+
-- Just ensure you keep ALL the columns defined here - they are required
|
|
13
|
+
-- by Better Auth to function correctly.
|
|
14
|
+
--
|
|
15
|
+
-- ============================================
|
|
16
|
+
|
|
17
|
+
-- ==========================================
|
|
18
|
+
-- Core Authentication Tables
|
|
19
|
+
-- ==========================================
|
|
20
|
+
|
|
21
|
+
-- Users
|
|
22
|
+
CREATE TABLE IF NOT EXISTS user (
|
|
23
|
+
id TEXT PRIMARY KEY,
|
|
24
|
+
name TEXT NOT NULL,
|
|
25
|
+
email TEXT NOT NULL UNIQUE,
|
|
26
|
+
emailVerified BOOLEAN NOT NULL,
|
|
27
|
+
image TEXT,
|
|
28
|
+
createdAt TIMESTAMP NOT NULL,
|
|
29
|
+
updatedAt TIMESTAMP NOT NULL
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
-- Sessions
|
|
33
|
+
CREATE TABLE IF NOT EXISTS session (
|
|
34
|
+
id TEXT PRIMARY KEY,
|
|
35
|
+
expiresAt TIMESTAMP NOT NULL,
|
|
36
|
+
token TEXT NOT NULL UNIQUE,
|
|
37
|
+
createdAt TIMESTAMP NOT NULL,
|
|
38
|
+
updatedAt TIMESTAMP NOT NULL,
|
|
39
|
+
ipAddress TEXT,
|
|
40
|
+
userAgent TEXT,
|
|
41
|
+
userId TEXT NOT NULL REFERENCES user(id) ON DELETE CASCADE
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
-- OAuth/Credential Accounts
|
|
45
|
+
CREATE TABLE IF NOT EXISTS account (
|
|
46
|
+
id TEXT PRIMARY KEY,
|
|
47
|
+
accountId TEXT NOT NULL,
|
|
48
|
+
providerId TEXT NOT NULL,
|
|
49
|
+
userId TEXT NOT NULL REFERENCES user(id) ON DELETE CASCADE,
|
|
50
|
+
accessToken TEXT,
|
|
51
|
+
refreshToken TEXT,
|
|
52
|
+
idToken TEXT,
|
|
53
|
+
accessTokenExpiresAt TIMESTAMP,
|
|
54
|
+
refreshTokenExpiresAt TIMESTAMP,
|
|
55
|
+
scope TEXT,
|
|
56
|
+
password TEXT,
|
|
57
|
+
createdAt TIMESTAMP NOT NULL,
|
|
58
|
+
updatedAt TIMESTAMP NOT NULL
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
-- Email/Token Verification
|
|
62
|
+
CREATE TABLE IF NOT EXISTS verification (
|
|
63
|
+
id TEXT PRIMARY KEY,
|
|
64
|
+
identifier TEXT NOT NULL,
|
|
65
|
+
value TEXT NOT NULL,
|
|
66
|
+
expiresAt TIMESTAMP NOT NULL,
|
|
67
|
+
createdAt TIMESTAMP,
|
|
68
|
+
updatedAt TIMESTAMP
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
-- ==========================================
|
|
72
|
+
-- Organization Plugin Tables
|
|
73
|
+
-- ==========================================
|
|
74
|
+
|
|
75
|
+
-- Organizations
|
|
76
|
+
CREATE TABLE IF NOT EXISTS organization (
|
|
77
|
+
id TEXT PRIMARY KEY,
|
|
78
|
+
name TEXT NOT NULL,
|
|
79
|
+
slug TEXT UNIQUE,
|
|
80
|
+
logo TEXT,
|
|
81
|
+
createdAt TIMESTAMP NOT NULL,
|
|
82
|
+
metadata TEXT -- JSON: Use for custom org data (e.g., billing, verification status)
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
-- Organization Members
|
|
86
|
+
CREATE TABLE IF NOT EXISTS member (
|
|
87
|
+
id TEXT PRIMARY KEY,
|
|
88
|
+
organizationId TEXT NOT NULL REFERENCES organization(id) ON DELETE CASCADE,
|
|
89
|
+
userId TEXT NOT NULL REFERENCES user(id) ON DELETE CASCADE,
|
|
90
|
+
role TEXT NOT NULL, -- 'owner', 'admin', 'member'
|
|
91
|
+
createdAt TIMESTAMP NOT NULL
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
-- Organization Invitations
|
|
95
|
+
CREATE TABLE IF NOT EXISTS invitation (
|
|
96
|
+
id TEXT PRIMARY KEY,
|
|
97
|
+
organizationId TEXT NOT NULL REFERENCES organization(id) ON DELETE CASCADE,
|
|
98
|
+
email TEXT NOT NULL,
|
|
99
|
+
role TEXT,
|
|
100
|
+
status TEXT NOT NULL, -- 'pending', 'accepted', 'rejected', 'expired'
|
|
101
|
+
expiresAt TIMESTAMP NOT NULL,
|
|
102
|
+
inviterId TEXT NOT NULL REFERENCES user(id) ON DELETE CASCADE
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
-- ==========================================
|
|
106
|
+
-- YOUR APPLICATION TABLES GO BELOW
|
|
107
|
+
-- ==========================================
|
|
108
|
+
-- Example:
|
|
109
|
+
--
|
|
110
|
+
-- CREATE TABLE IF NOT EXISTS my_entity (
|
|
111
|
+
-- id TEXT PRIMARY KEY,
|
|
112
|
+
-- org_id TEXT NOT NULL, -- References organization.id
|
|
113
|
+
-- name TEXT NOT NULL,
|
|
114
|
+
-- created_at INTEGER
|
|
115
|
+
-- );
|