sonamu 0.10.7 → 0.10.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cli.js +10 -253
- package/dist/migration/code-generation.js +2 -2
- package/dist/ui-web/assets/{index-D0MHYbxl.js → index-CJf8uJYf.js} +47 -41
- package/dist/ui-web/assets/index-GMMIVGja.css +1 -0
- package/dist/ui-web/index.html +2 -2
- package/package.json +3 -3
- package/src/bin/cli.ts +12 -375
- package/src/migration/code-generation.ts +1 -1
- package/dist/ui-web/assets/index-Dx_JX4aQ.css +0 -1
- package/src/skills/AGENTS.md +0 -108
- package/src/skills/sonamu/SKILL.md +0 -75
- package/src/skills/sonamu-ai-agents/SKILL.md +0 -205
- package/src/skills/sonamu-api/SKILL.md +0 -480
- package/src/skills/sonamu-auth/SKILL.md +0 -327
- package/src/skills/sonamu-auth/references/plugins.md +0 -310
- package/src/skills/sonamu-auth/references/user-id-migration-followups.md +0 -192
- package/src/skills/sonamu-auth/references/user-id-migration.md +0 -455
- package/src/skills/sonamu-config/SKILL.md +0 -203
- package/src/skills/sonamu-config/references/database.md +0 -452
- package/src/skills/sonamu-config/references/environments.md +0 -178
- package/src/skills/sonamu-config/references/server-options.md +0 -400
- package/src/skills/sonamu-entity/SKILL.md +0 -180
- package/src/skills/sonamu-entity/references/creation-workflow.md +0 -581
- package/src/skills/sonamu-entity/references/design-guides.md +0 -243
- package/src/skills/sonamu-entity/references/field-types.md +0 -170
- package/src/skills/sonamu-entity/references/relations-detail.md +0 -245
- package/src/skills/sonamu-entity/references/relations.md +0 -463
- package/src/skills/sonamu-entity/references/subset.md +0 -156
- package/src/skills/sonamu-fixture/SKILL.md +0 -180
- package/src/skills/sonamu-fixture/references/cli-usage.md +0 -439
- package/src/skills/sonamu-fixture/references/cone.md +0 -298
- package/src/skills/sonamu-frontend/SKILL.md +0 -142
- package/src/skills/sonamu-frontend/references/components.md +0 -323
- package/src/skills/sonamu-frontend/references/examples.md +0 -64
- package/src/skills/sonamu-frontend/references/hooks.md +0 -273
- package/src/skills/sonamu-frontend/references/runtime.md +0 -165
- package/src/skills/sonamu-frontend/references/scaffolding.md +0 -439
- package/src/skills/sonamu-i18n/SKILL.md +0 -287
- package/src/skills/sonamu-migration/SKILL.md +0 -316
- package/src/skills/sonamu-naite/SKILL.md +0 -266
- package/src/skills/sonamu-query/SKILL.md +0 -48
- package/src/skills/sonamu-query/references/model-patterns.md +0 -390
- package/src/skills/sonamu-query/references/model.md +0 -366
- package/src/skills/sonamu-query/references/puri.md +0 -413
- package/src/skills/sonamu-query/references/search.md +0 -238
- package/src/skills/sonamu-query/references/upsert.md +0 -324
- package/src/skills/sonamu-tasks/SKILL.md +0 -236
- package/src/skills/sonamu-testing/SKILL.md +0 -251
- package/src/skills/sonamu-testing/references/devrunner.md +0 -405
- package/src/skills/sonamu-testing/references/helpers.md +0 -185
- package/src/skills/sonamu-testing/references/patterns.md +0 -263
- package/src/skills/sonamu-testing/references/pitfalls.md +0 -588
- package/src/skills/sonamu-testing/references/quick-start.md +0 -285
- package/src/skills/sonamu-testing/references/type-safety.md +0 -172
- package/src/skills/sonamu-testing/references/writing-plan.md +0 -375
- package/src/skills/sonamu-vector/SKILL.md +0 -222
|
@@ -1,327 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: sonamu-auth
|
|
3
|
-
description: Sets up better-auth in a Sonamu project. Use when running auth generate, applying Guards to an endpoint, reading the session from Context, adding an auth plugin, or migrating User.id to a string primary key. Covers the generated User/Account/Session/Verification entities, guard configuration, and the admin, organization, 2fa, and passkey plugin wrappers.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# better-auth Authentication System
|
|
7
|
-
|
|
8
|
-
**Plugin wrappers** (admin, organization, 2fa, passkey and 6 more, plus snake_case mapping):
|
|
9
|
-
see `references/plugins.md`.
|
|
10
|
-
|
|
11
|
-
**Changing User.id to a string PK** for external auth: see `references/user-id-migration.md`.
|
|
12
|
-
|
|
13
|
-
> This document is based on actual Sonamu source code.
|
|
14
|
-
|
|
15
|
-
## Automatic Entity Generation
|
|
16
|
-
|
|
17
|
-
**Source code:**
|
|
18
|
-
|
|
19
|
-
- CLI: `modules/sonamu/src/bin/cli.ts` (auth_generate function)
|
|
20
|
-
- Generation logic: `modules/sonamu/src/auth/auth-generator.ts`
|
|
21
|
-
- Entity definitions: `modules/sonamu/src/auth/better-auth-entities.ts`
|
|
22
|
-
|
|
23
|
-
**IMPORTANT: Before running generate, you must confirm with the user which plugins they want to use.**
|
|
24
|
-
|
|
25
|
-
Plugin selection happens at generate time and can be added later, but it is best to specify them from the start.
|
|
26
|
-
Refer to `references/plugins.md` for the list of supported plugins and their purposes.
|
|
27
|
-
|
|
28
|
-
### Plugin Confirmation Flow
|
|
29
|
-
|
|
30
|
-
**[Step 1] Confirm before generate (required)**
|
|
31
|
-
|
|
32
|
-
> "What authentication method do you plan to use? Please confirm whether you need additional plugins beyond the default email/social login.
|
|
33
|
-
> Supported plugins: `admin`, `organization`, `2fa`, `username`, `phone-number`, `api-key`, `jwt`, `passkey`, `sso`, `anonymous`"
|
|
34
|
-
|
|
35
|
-
**[Step 1-A] If the user responds "I'll do it later":**
|
|
36
|
-
|
|
37
|
-
Provide the following guidance and proceed with generate without plugins:
|
|
38
|
-
|
|
39
|
-
> "Understood. It's best to add plugins before the initial migration is run.
|
|
40
|
-
> I'll confirm again before the migration."
|
|
41
|
-
|
|
42
|
-
And remember the **`plugins_deferred: true`** state.
|
|
43
|
-
|
|
44
|
-
**[Step 2] Re-confirm just before migrate run (CRITICAL — must be done if `plugins_deferred: true`)**
|
|
45
|
-
|
|
46
|
-
Before running the migration, always confirm again:
|
|
47
|
-
|
|
48
|
-
> "You are about to run a migration. This is the best time to add plugins.
|
|
49
|
-
> If you want to add any plugins, please let me know. Otherwise, we'll proceed as-is.
|
|
50
|
-
> Supported plugins: `admin`, `organization`, `2fa`, `username`, `phone-number`, `api-key`, `jwt`, `passkey`, `sso`, `anonymous`"
|
|
51
|
-
|
|
52
|
-
- If adding plugins: run `pnpm sonamu auth generate --plugins <list>` then proceed with migrate
|
|
53
|
-
- If none: proceed with migrate as-is
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
# Basic entities only, no plugins
|
|
57
|
-
pnpm sonamu auth generate
|
|
58
|
-
|
|
59
|
-
# With plugins
|
|
60
|
-
pnpm sonamu auth generate --plugins admin,2fa,username
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
The 4 entities generated (`betterAuthV1` array):
|
|
64
|
-
|
|
65
|
-
| Entity | Table | Key fields |
|
|
66
|
-
| ------------ | ------------- | -------------------------------------- |
|
|
67
|
-
| User | users | id, name, email, email_verified, image |
|
|
68
|
-
| Session | sessions | id, token, expires_at, user_id |
|
|
69
|
-
| Account | accounts | id, provider_id, access_token, user_id |
|
|
70
|
-
| Verification | verifications | id, identifier, value, expires_at |
|
|
71
|
-
|
|
72
|
-
**How it works:**
|
|
73
|
-
|
|
74
|
-
- If the entity does not exist, it is created fresh
|
|
75
|
-
- If the entity already exists, only missing fields are added
|
|
76
|
-
- Fields with changed types are updated automatically
|
|
77
|
-
- Uses snake_case column names (better-auth uses camelCase)
|
|
78
|
-
|
|
79
|
-
## Adding Fixture Companions (`auth add-companions`)
|
|
80
|
-
|
|
81
|
-
After running `auth generate`, run this command once to add `fixtureCompanions` to the `id` prop of better-auth entities (User, etc.).
|
|
82
|
-
|
|
83
|
-
```bash
|
|
84
|
-
pnpm sonamu auth add-companions
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
**Purpose:** Enables automatic Account fixture creation when generating User fixtures. Without this, fixture gen creates User records without a corresponding credentials Account, breaking auth-dependent tests.
|
|
88
|
-
|
|
89
|
-
**What it does:**
|
|
90
|
-
- Reads `fixtureCompanions` from the `betterAuthV1` definitions
|
|
91
|
-
- Adds them to the existing entity.json `id` prop's cone
|
|
92
|
-
- Skips if `fixtureCompanions` already exists
|
|
93
|
-
|
|
94
|
-
**When to run:** Once, after `auth generate`, before running `fixture gen` for the first time. Re-running is safe (idempotent).
|
|
95
|
-
|
|
96
|
-
## Field Mapping (Applied Automatically)
|
|
97
|
-
|
|
98
|
-
**Source code:** `modules/sonamu/src/auth/better-auth-entities.ts` (BASE_FIELD_MAPPINGS)
|
|
99
|
-
|
|
100
|
-
| better-auth | Sonamu |
|
|
101
|
-
| --------------- | ---------------- |
|
|
102
|
-
| `emailVerified` | `email_verified` |
|
|
103
|
-
| `createdAt` | `created_at` |
|
|
104
|
-
| `userId` | `user_id` |
|
|
105
|
-
| `expiresAt` | `expires_at` |
|
|
106
|
-
|
|
107
|
-
## Config Setup
|
|
108
|
-
|
|
109
|
-
**Source code:** `modules/sonamu/src/api/config.ts` (SonamuServerOptions.auth)
|
|
110
|
-
|
|
111
|
-
```typescript
|
|
112
|
-
// sonamu.config.ts
|
|
113
|
-
server: {
|
|
114
|
-
auth: {
|
|
115
|
-
emailAndPassword: { enabled: true },
|
|
116
|
-
// To add social login:
|
|
117
|
-
// socialProviders: {
|
|
118
|
-
// google: {
|
|
119
|
-
// clientId: process.env.GOOGLE_CLIENT_ID!,
|
|
120
|
-
// clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
|
|
121
|
-
// },
|
|
122
|
-
// },
|
|
123
|
-
},
|
|
124
|
-
}
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
## API Endpoints (Auto-registered)
|
|
128
|
-
|
|
129
|
-
| Path | Method | Description |
|
|
130
|
-
| ------------------------- | ------ | ----------- |
|
|
131
|
-
| `/api/auth/sign-up/email` | POST | Sign up |
|
|
132
|
-
| `/api/auth/sign-in/email` | POST | Sign in |
|
|
133
|
-
| `/api/auth/sign-out` | POST | Sign out |
|
|
134
|
-
| `/api/auth/get-session` | GET | Get session |
|
|
135
|
-
|
|
136
|
-
## Accessing user/session from Context
|
|
137
|
-
|
|
138
|
-
**Source code:** `modules/sonamu/src/api/context.ts` (AuthContext type definition)
|
|
139
|
-
|
|
140
|
-
```typescript
|
|
141
|
-
import { Sonamu } from "sonamu";
|
|
142
|
-
|
|
143
|
-
@api({ httpMethod: "GET", guards: ["user"] })
|
|
144
|
-
async me(): Promise<UserSubsetA | null> {
|
|
145
|
-
const { user, session } = Sonamu.getContext();
|
|
146
|
-
|
|
147
|
-
if (!user) return null;
|
|
148
|
-
|
|
149
|
-
// user.id, user.email, user.name, etc. are accessible
|
|
150
|
-
return this.findById("A", user.id);
|
|
151
|
-
}
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
## Using Guards
|
|
155
|
-
|
|
156
|
-
**Source code:** `modules/sonamu/src/api/decorators.ts` (GuardKeys interface)
|
|
157
|
-
|
|
158
|
-
### Built-in Guards
|
|
159
|
-
|
|
160
|
-
Sonamu provides 3 default guards:
|
|
161
|
-
|
|
162
|
-
- `query`: allows all users (including unauthenticated)
|
|
163
|
-
- `user`: allows only authenticated users
|
|
164
|
-
- `admin`: allows only users with admin privileges
|
|
165
|
-
|
|
166
|
-
```typescript
|
|
167
|
-
// Login required
|
|
168
|
-
@api({ httpMethod: "GET", guards: ["user"] })
|
|
169
|
-
async getProfile() {
|
|
170
|
-
const { user } = Sonamu.getContext();
|
|
171
|
-
return { userId: user.id };
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Admin only (requires adding a role field to the User entity)
|
|
175
|
-
@api({ httpMethod: "DELETE", guards: ["admin"] })
|
|
176
|
-
async deleteUser(id: string) {
|
|
177
|
-
// Only admins can execute
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### Adding Custom Guards
|
|
182
|
-
|
|
183
|
-
If additional permissions beyond the default guards are needed, extend the `GuardKeys` interface in `src/typings/sonamu.d.ts`.
|
|
184
|
-
|
|
185
|
-
**File location:** `src/typings/sonamu.d.ts`
|
|
186
|
-
|
|
187
|
-
```typescript
|
|
188
|
-
import {} from "sonamu";
|
|
189
|
-
|
|
190
|
-
declare module "sonamu" {
|
|
191
|
-
export interface GuardKeys {
|
|
192
|
-
query: true;
|
|
193
|
-
user: true;
|
|
194
|
-
admin: true;
|
|
195
|
-
// Custom guards
|
|
196
|
-
manager: true;
|
|
197
|
-
evaluator: true;
|
|
198
|
-
superadmin: true;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
You can now use the added guards in the `@api` decorator:
|
|
204
|
-
|
|
205
|
-
```typescript
|
|
206
|
-
// Manager permission
|
|
207
|
-
@api({ httpMethod: "GET", guards: ["manager"] })
|
|
208
|
-
async getReports() {
|
|
209
|
-
// Only managers can execute
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// Allow multiple guards simultaneously
|
|
213
|
-
@api({ httpMethod: "POST", guards: ["admin", "manager"] })
|
|
214
|
-
async createReport() {
|
|
215
|
-
// Requires admin or manager permission
|
|
216
|
-
}
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
## Implementing guardHandler
|
|
220
|
-
|
|
221
|
-
**Source code:** `modules/sonamu/src/api/config.ts` (SonamuFastifyConfig.guardHandler)
|
|
222
|
-
|
|
223
|
-
```typescript
|
|
224
|
-
import { Sonamu } from "sonamu";
|
|
225
|
-
|
|
226
|
-
// sonamu.config.ts
|
|
227
|
-
apiConfig: {
|
|
228
|
-
guardHandler: (guard, request, api) => {
|
|
229
|
-
const { user } = Sonamu.getContext();
|
|
230
|
-
|
|
231
|
-
switch (guard) {
|
|
232
|
-
case "user":
|
|
233
|
-
if (!user) {
|
|
234
|
-
throw new Error("Login is required");
|
|
235
|
-
}
|
|
236
|
-
break;
|
|
237
|
-
|
|
238
|
-
case "admin":
|
|
239
|
-
// Requires adding a role field to the User entity
|
|
240
|
-
if (!user || (user as any).role !== "admin") {
|
|
241
|
-
throw new Error("Only admins can access this");
|
|
242
|
-
}
|
|
243
|
-
break;
|
|
244
|
-
|
|
245
|
-
case "manager":
|
|
246
|
-
// Custom guard: manager permission
|
|
247
|
-
if (!user || !["admin", "manager"].includes((user as any).role)) {
|
|
248
|
-
throw new Error("Manager permission is required");
|
|
249
|
-
}
|
|
250
|
-
break;
|
|
251
|
-
|
|
252
|
-
case "evaluator":
|
|
253
|
-
// Custom guard: evaluator permission
|
|
254
|
-
if (!user || !["admin", "evaluator"].includes((user as any).role)) {
|
|
255
|
-
throw new Error("Evaluator permission is required");
|
|
256
|
-
}
|
|
257
|
-
break;
|
|
258
|
-
|
|
259
|
-
case "query":
|
|
260
|
-
// Allow all users
|
|
261
|
-
break;
|
|
262
|
-
}
|
|
263
|
-
},
|
|
264
|
-
}
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
## Adding role to the User Entity (Role-based Authorization)
|
|
268
|
-
|
|
269
|
-
**Note:** The default User entity from better-auth (`modules/sonamu/src/auth/better-auth-entities.ts`) does not have a `role` field.
|
|
270
|
-
|
|
271
|
-
If role-based authorization is needed, add it directly to the User entity:
|
|
272
|
-
|
|
273
|
-
```json
|
|
274
|
-
// src/application/sonamu.entity.json
|
|
275
|
-
{
|
|
276
|
-
"id": "User",
|
|
277
|
-
"props": [
|
|
278
|
-
// ... existing fields
|
|
279
|
-
{
|
|
280
|
-
"name": "role",
|
|
281
|
-
"type": "string",
|
|
282
|
-
"default": "user",
|
|
283
|
-
"desc": "User role (user, admin, manager)"
|
|
284
|
-
}
|
|
285
|
-
]
|
|
286
|
-
}
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
Adding an enum:
|
|
290
|
-
|
|
291
|
-
```json
|
|
292
|
-
{
|
|
293
|
-
"enums": {
|
|
294
|
-
"UserRole": {
|
|
295
|
-
"user": "Regular user",
|
|
296
|
-
"admin": "Administrator",
|
|
297
|
-
"manager": "Manager"
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
## Checklist
|
|
304
|
-
|
|
305
|
-
After setup, verify:
|
|
306
|
-
|
|
307
|
-
- [ ] **[Before generate] Confirm with user whether plugins are needed**
|
|
308
|
-
- If "later" → remember `plugins_deferred: true`, guide on optimal timing
|
|
309
|
-
- [ ] Run `pnpm sonamu auth generate [--plugins ...]`
|
|
310
|
-
- [ ] **[Before migrate] Re-confirm plugins if `plugins_deferred: true`** (CRITICAL)
|
|
311
|
-
- [ ] Create and apply migration
|
|
312
|
-
- [ ] Configure `server.auth` in `sonamu.config.ts`
|
|
313
|
-
- [ ] Implement `guardHandler`
|
|
314
|
-
- [ ] Confirm user/session access from Context
|
|
315
|
-
- [ ] Add role to User entity if role-based authorization is needed
|
|
316
|
-
|
|
317
|
-
## Reference
|
|
318
|
-
|
|
319
|
-
**Skills documentation:**
|
|
320
|
-
|
|
321
|
-
- Detailed configuration: "server.auth details" section in `sonamu-config`
|
|
322
|
-
- Context API: "Context access" section in `sonamu-api`
|
|
323
|
-
|
|
324
|
-
**Official documentation:**
|
|
325
|
-
|
|
326
|
-
- Korean: `modules/docs/ko/api-development/authentication/setup.mdx`
|
|
327
|
-
- English: `modules/docs/en/api-development/authentication/setup.mdx`
|
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
# better-auth Plugin Guide
|
|
2
|
-
|
|
3
|
-
Sonamu wraps better-auth plugins with snake_case schema mapping.
|
|
4
|
-
Use the `auth generate --plugins` command to auto-generate plugin entities.
|
|
5
|
-
|
|
6
|
-
**Source code:**
|
|
7
|
-
|
|
8
|
-
- Wrappers: `modules/sonamu/src/auth/plugins/wrappers/`
|
|
9
|
-
- Entity definitions: `modules/sonamu/src/auth/plugins/entity-definitions/`
|
|
10
|
-
- Generator: `modules/sonamu/src/auth/auth-generator.ts`
|
|
11
|
-
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
## Supported Plugins
|
|
15
|
-
|
|
16
|
-
| Plugin ID | Wrapper function | Package | Purpose |
|
|
17
|
-
| -------------- | ---------------- | ----------------------- | ----------------------------------------------------- |
|
|
18
|
-
| `admin` | `admin()` | `better-auth/plugins` | Admin features, user ban/unban, session impersonation |
|
|
19
|
-
| `organization` | `organization()` | `better-auth/plugins` | Organization, team, member, and invitation management |
|
|
20
|
-
| `2fa` | `twoFactor()` | `better-auth/plugins` | TOTP-based two-factor authentication |
|
|
21
|
-
| `username` | `username()` | `better-auth/plugins` | Username-based authentication |
|
|
22
|
-
| `phone-number` | `phoneNumber()` | `better-auth/plugins` | Phone number authentication |
|
|
23
|
-
| `api-key` | `apiKey()` | `@better-auth/api-key` | API key issuance/management, rate limiting |
|
|
24
|
-
| `jwt` | `jwt()` | `better-auth/plugins` | JWT tokens + JWKS key management |
|
|
25
|
-
| `passkey` | `passkey()` | `@better-auth/passkey` | WebAuthn/Passkey authentication |
|
|
26
|
-
| `sso` | `sso()` | `@better-auth/sso` | OIDC/SAML SSO integration |
|
|
27
|
-
| `anonymous` | `anonymous()` | `better-auth/plugins` | Anonymous user support |
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
## CLI Usage
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
# Base entities only (User, Session, Account, Verification)
|
|
35
|
-
pnpm sonamu auth generate
|
|
36
|
-
|
|
37
|
-
# With plugins
|
|
38
|
-
pnpm sonamu auth generate --plugins admin,organization
|
|
39
|
-
|
|
40
|
-
# Multiple plugins
|
|
41
|
-
pnpm sonamu auth generate --plugins admin,2fa,phone-number,username
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### How It Works
|
|
45
|
-
|
|
46
|
-
1. **Base entities** are created/updated (User, Session, Account, Verification)
|
|
47
|
-
2. **Per-plugin** processing:
|
|
48
|
-
- `entities`: creates new tables (e.g. Organization → organizations, members, invitations, teams, team_members)
|
|
49
|
-
- `additionalProps`: adds fields to existing entities (e.g. admin → adds ban_reason, ban_expires to User)
|
|
50
|
-
- `additionalIndexes`: adds indexes to existing entities
|
|
51
|
-
3. Entities that already exist have **only missing fields added**; existing fields are preserved
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## Wrapper Usage (sonamu.config.ts)
|
|
56
|
-
|
|
57
|
-
Using Sonamu wrappers automatically applies snake_case schema mapping.
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
// sonamu.config.ts
|
|
61
|
-
import { admin, organization, twoFactor, username } from "sonamu/auth/plugins";
|
|
62
|
-
|
|
63
|
-
export default defineConfig({
|
|
64
|
-
server: {
|
|
65
|
-
auth: {
|
|
66
|
-
emailAndPassword: { enabled: true },
|
|
67
|
-
plugins: [admin(), organization(), twoFactor(), username()],
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
});
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
**CRITICAL: Do not import directly from `better-auth/plugins`.** You must go through the Sonamu wrapper for snake_case mapping to apply.
|
|
74
|
-
|
|
75
|
-
```typescript
|
|
76
|
-
// WRONG - snake_case mapping not applied
|
|
77
|
-
import { admin } from "better-auth/plugins";
|
|
78
|
-
|
|
79
|
-
// CORRECT - Sonamu wrapper
|
|
80
|
-
import { admin } from "sonamu/auth/plugins";
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
## Per-Plugin Details
|
|
86
|
-
|
|
87
|
-
### admin
|
|
88
|
-
|
|
89
|
-
**Additional entities:** None
|
|
90
|
-
**Fields added to User:** `role`, `banned`, `ban_reason`, `ban_expires`
|
|
91
|
-
**Fields added to Session:** `impersonated_by`
|
|
92
|
-
|
|
93
|
-
```typescript
|
|
94
|
-
import { admin } from "sonamu/auth/plugins";
|
|
95
|
-
|
|
96
|
-
// Basic usage
|
|
97
|
-
admin();
|
|
98
|
-
|
|
99
|
-
// Customize options (schema mapping is automatically merged)
|
|
100
|
-
admin({ defaultRole: "user" });
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Schema mapping:
|
|
104
|
-
|
|
105
|
-
- `banReason` → `ban_reason`
|
|
106
|
-
- `banExpires` → `ban_expires`
|
|
107
|
-
- `impersonatedBy` → `impersonated_by`
|
|
108
|
-
|
|
109
|
-
### organization
|
|
110
|
-
|
|
111
|
-
**Additional entities:** Organization, Member, Invitation, Team, TeamMember
|
|
112
|
-
**Fields added to Session:** `active_organization_id`, `active_team_id`
|
|
113
|
-
|
|
114
|
-
```typescript
|
|
115
|
-
import { organization } from "sonamu/auth/plugins";
|
|
116
|
-
|
|
117
|
-
organization();
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
Schema mapping:
|
|
121
|
-
|
|
122
|
-
- All tables: `createdAt` → `created_at`
|
|
123
|
-
- Member: `userId` → `user_id`, `organizationId` → `organization_id`
|
|
124
|
-
- Invitation: `inviterId` → `inviter_id`, `organizationId` → `organization_id`, `teamId` → `team_id`, `expiresAt` → `expires_at`
|
|
125
|
-
- Team: `organizationId` → `organization_id`, `updatedAt` → `updated_at`
|
|
126
|
-
- TeamMember: `teamId` → `team_id`, `userId` → `user_id`
|
|
127
|
-
- Session: `activeOrganizationId` → `active_organization_id`, `activeTeamId` → `active_team_id`
|
|
128
|
-
|
|
129
|
-
### 2fa (twoFactor)
|
|
130
|
-
|
|
131
|
-
**Additional entities:** TwoFactor
|
|
132
|
-
**Fields added to User:** `two_factor_enabled`
|
|
133
|
-
|
|
134
|
-
```typescript
|
|
135
|
-
import { twoFactor } from "sonamu/auth/plugins";
|
|
136
|
-
|
|
137
|
-
twoFactor();
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
Schema mapping:
|
|
141
|
-
|
|
142
|
-
- User: `twoFactorEnabled` → `two_factor_enabled`
|
|
143
|
-
- TwoFactor: `userId` → `user_id`, `backupCodes` → `backup_codes`
|
|
144
|
-
|
|
145
|
-
### username
|
|
146
|
-
|
|
147
|
-
**Fields added to User:** `display_username`
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
import { username } from "sonamu/auth/plugins";
|
|
151
|
-
|
|
152
|
-
username();
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
Schema mapping:
|
|
156
|
-
|
|
157
|
-
- `displayUsername` → `display_username`
|
|
158
|
-
|
|
159
|
-
### phone-number
|
|
160
|
-
|
|
161
|
-
**Fields added to User:** `phone_number`, `phone_number_verified`
|
|
162
|
-
|
|
163
|
-
```typescript
|
|
164
|
-
import { phoneNumber } from "sonamu/auth/plugins";
|
|
165
|
-
|
|
166
|
-
phoneNumber({
|
|
167
|
-
sendOTP: async ({ phoneNumber, otp }) => {
|
|
168
|
-
/* send SMS */
|
|
169
|
-
},
|
|
170
|
-
});
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
Schema mapping:
|
|
174
|
-
|
|
175
|
-
- `phoneNumber` → `phone_number`
|
|
176
|
-
- `phoneNumberVerified` → `phone_number_verified`
|
|
177
|
-
|
|
178
|
-
### api-key
|
|
179
|
-
|
|
180
|
-
**Additional entities:** ApiKey (table: `api_keys`)
|
|
181
|
-
**Package:** `@better-auth/api-key` (must be installed separately)
|
|
182
|
-
|
|
183
|
-
```bash
|
|
184
|
-
pnpm add @better-auth/api-key
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
```typescript
|
|
188
|
-
import { apiKey } from "sonamu/auth/plugins";
|
|
189
|
-
|
|
190
|
-
apiKey();
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
Schema mapping:
|
|
194
|
-
|
|
195
|
-
- `referenceId` → `reference_id`, `configId` → `config_id`
|
|
196
|
-
- `lastRequest` → `last_request`, `requestCount` → `request_count`
|
|
197
|
-
- `rateLimitEnabled` → `rate_limit_enabled`, `rateLimitTimeWindow` → `rate_limit_time_window`
|
|
198
|
-
- `rateLimitMax` → `rate_limit_max`, `refillInterval` → `refill_interval`
|
|
199
|
-
- `refillAmount` → `refill_amount`, `lastRefillAt` → `last_refill_at`
|
|
200
|
-
- `expiresAt` → `expires_at`, `createdAt` → `created_at`, `updatedAt` → `updated_at`
|
|
201
|
-
|
|
202
|
-
Note: v1.5.0에서 `userId`가 `referenceId`로 변경됨. `referenceId`는 user 또는 organization을 참조하는 polymorphic ID.
|
|
203
|
-
|
|
204
|
-
### jwt
|
|
205
|
-
|
|
206
|
-
**Additional entities:** Jwks (table: `jwks`)
|
|
207
|
-
|
|
208
|
-
```typescript
|
|
209
|
-
import { jwt } from "sonamu/auth/plugins";
|
|
210
|
-
|
|
211
|
-
jwt();
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
Schema mapping:
|
|
215
|
-
|
|
216
|
-
- `publicKey` → `public_key`, `privateKey` → `private_key`
|
|
217
|
-
- `createdAt` → `created_at`, `expiresAt` → `expires_at`
|
|
218
|
-
|
|
219
|
-
### passkey
|
|
220
|
-
|
|
221
|
-
**Additional entities:** Passkey (table: `passkeys`)
|
|
222
|
-
**Package:** `@better-auth/passkey` (must be installed separately)
|
|
223
|
-
|
|
224
|
-
```bash
|
|
225
|
-
pnpm add @better-auth/passkey
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
```typescript
|
|
229
|
-
import { passkey } from "sonamu/auth/plugins";
|
|
230
|
-
|
|
231
|
-
passkey({ rpID: "localhost", rpName: "My App" });
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
Schema mapping:
|
|
235
|
-
|
|
236
|
-
- `publicKey` → `public_key`, `userId` → `user_id`, `credentialID` → `credential_id`
|
|
237
|
-
- `deviceType` → `device_type`, `backedUp` → `backed_up`, `createdAt` → `created_at`
|
|
238
|
-
|
|
239
|
-
### sso
|
|
240
|
-
|
|
241
|
-
**Package:** `@better-auth/sso` (must be installed separately)
|
|
242
|
-
|
|
243
|
-
```bash
|
|
244
|
-
pnpm add @better-auth/sso
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
```typescript
|
|
248
|
-
import { sso } from "sonamu/auth/plugins";
|
|
249
|
-
|
|
250
|
-
sso();
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
Table: `sso_providers`
|
|
254
|
-
Schema mapping:
|
|
255
|
-
|
|
256
|
-
- `oidcConfig` → `oidc_config`, `samlConfig` → `saml_config`
|
|
257
|
-
- `userId` → `user_id`, `providerId` → `provider_id`, `organizationId` → `organization_id`
|
|
258
|
-
|
|
259
|
-
### anonymous
|
|
260
|
-
|
|
261
|
-
**Fields added to User:** `is_anonymous`
|
|
262
|
-
|
|
263
|
-
```typescript
|
|
264
|
-
import { anonymous } from "sonamu/auth/plugins";
|
|
265
|
-
|
|
266
|
-
anonymous();
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
Schema mapping:
|
|
270
|
-
|
|
271
|
-
- `isAnonymous` → `is_anonymous`
|
|
272
|
-
|
|
273
|
-
---
|
|
274
|
-
|
|
275
|
-
## Custom Schema Options
|
|
276
|
-
|
|
277
|
-
Passing additional options to a wrapper function automatically merges them with Sonamu's default mapping:
|
|
278
|
-
|
|
279
|
-
```typescript
|
|
280
|
-
admin({
|
|
281
|
-
defaultRole: "user",
|
|
282
|
-
schema: {
|
|
283
|
-
user: {
|
|
284
|
-
fields: {
|
|
285
|
-
customField: "custom_field", // additional mapping
|
|
286
|
-
},
|
|
287
|
-
},
|
|
288
|
-
},
|
|
289
|
-
});
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
Internally, `merge(ADMIN_SCHEMA, options.schema)` is executed to preserve the Sonamu mapping.
|
|
293
|
-
|
|
294
|
-
---
|
|
295
|
-
|
|
296
|
-
## Steps After Adding a Plugin
|
|
297
|
-
|
|
298
|
-
1. `pnpm sonamu auth generate --plugins <plugin list>`
|
|
299
|
-
2. Confirm generated entities in Sonamu UI
|
|
300
|
-
3. Run migration with `pnpm sonamu migrate run`
|
|
301
|
-
4. Add wrapper functions to `sonamu.config.ts`
|
|
302
|
-
5. If needed, add plugin-specific permission logic to `guardHandler`
|
|
303
|
-
|
|
304
|
-
---
|
|
305
|
-
|
|
306
|
-
## References
|
|
307
|
-
|
|
308
|
-
- **Basic auth configuration:** `sonamu-auth`
|
|
309
|
-
- **Changing PK type (better-auth → string PK):** `references/user-id-migration.md`
|
|
310
|
-
- **Source code:** `modules/sonamu/src/auth/plugins/`
|