@fougere/auth-better 0.2.0-alpha.2 → 0.4.0-alpha.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/README.md +1 -1
- package/dist/adapter.js.map +1 -1
- package/package.json +6 -5
- package/src/adapter.ts +189 -0
- package/src/entities.ts +94 -0
- package/src/index.ts +101 -0
- package/src/translate.ts +81 -0
package/README.md
CHANGED
|
@@ -13,4 +13,4 @@ pnpm add @fougere/auth-better
|
|
|
13
13
|
|
|
14
14
|
Part of [Fougere](https://github.com/chok/fougere) — one schema, a gradient from
|
|
15
15
|
monolith to distributed, the same user code.
|
|
16
|
-
Reference documentation: [the site](https://
|
|
16
|
+
Reference documentation: [the site](https://fougere.dev/) (en/fr).
|
package/dist/adapter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fougere/auth-better",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0-alpha.0",
|
|
4
4
|
"description": "Fougere's auth — a translation layer onto better-auth.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fougere",
|
|
@@ -25,17 +25,18 @@
|
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
27
|
"files": [
|
|
28
|
-
"dist"
|
|
28
|
+
"dist",
|
|
29
|
+
"src"
|
|
29
30
|
],
|
|
30
31
|
"dependencies": {
|
|
31
32
|
"@paralleldrive/cuid2": "^3.3.0",
|
|
32
33
|
"better-auth": "^1.6.11",
|
|
33
|
-
"@fougere/core": "0.
|
|
34
|
-
"@fougere/schema": "0.
|
|
34
|
+
"@fougere/core": "0.4.0-alpha.0",
|
|
35
|
+
"@fougere/schema": "0.4.0-alpha.0"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
38
|
"vitest": "^4.1.0",
|
|
38
|
-
"@fougere/adapter-sql": "0.
|
|
39
|
+
"@fougere/adapter-sql": "0.4.0-alpha.0"
|
|
39
40
|
},
|
|
40
41
|
"publishConfig": {
|
|
41
42
|
"access": "public"
|
package/src/adapter.ts
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { createAdapterFactory } from 'better-auth/adapters';
|
|
2
|
+
import type { CleanedWhere, CustomAdapter } from 'better-auth/adapters';
|
|
3
|
+
import type { EntityOrm } from '@fougere/core';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Map of better-auth model names ('user', 'session', 'account', ...)
|
|
7
|
+
* to Fougere EntityOrm instances. Built once at boot by create() in index.ts.
|
|
8
|
+
*/
|
|
9
|
+
export type OrmMap = Map<string, EntityOrm>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Where[] supported subset:
|
|
13
|
+
* - All clauses use 'eq' operator
|
|
14
|
+
* - Implicit AND between clauses (no OR connector)
|
|
15
|
+
* Anything else throws — extend EntityOrm or add an engine-level fallback when needed.
|
|
16
|
+
*/
|
|
17
|
+
function whereToCriteria(where: readonly CleanedWhere[]): Record<string, unknown> {
|
|
18
|
+
const criteria: Record<string, unknown> = {};
|
|
19
|
+
for (const clause of where) {
|
|
20
|
+
if (clause.operator !== 'eq') {
|
|
21
|
+
throw new Error(
|
|
22
|
+
`[fougereAdapter] Operator '${clause.operator}' not yet supported on field '${clause.field}'. ` +
|
|
23
|
+
`Only 'eq' with implicit AND is implemented.`,
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
if (clause.connector === 'OR') {
|
|
27
|
+
throw new Error(`[fougereAdapter] OR connector not yet supported (field '${clause.field}').`);
|
|
28
|
+
}
|
|
29
|
+
criteria[clause.field] = clause.value;
|
|
30
|
+
}
|
|
31
|
+
return criteria;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function getOrm(ormMap: OrmMap, model: string): EntityOrm {
|
|
35
|
+
const orm = ormMap.get(model);
|
|
36
|
+
if (!orm) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`[fougereAdapter] Unknown model '${model}'. ` +
|
|
39
|
+
`Known models: ${[...ormMap.keys()].join(', ')}. ` +
|
|
40
|
+
`Plugins that ship their own schema need entities registered explicitly.`,
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return orm;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Better-auth adapter that routes every operation through Fougere EntityOrm.
|
|
48
|
+
*
|
|
49
|
+
* This closes the loop: the same `db` resolved by Fougere's bootstrap is the
|
|
50
|
+
* one EntityOrm writes to, and better-auth never touches the storage directly.
|
|
51
|
+
* If Fougere swaps Kysely for another backend, this adapter follows for free.
|
|
52
|
+
*/
|
|
53
|
+
export function fougereAdapter(ormMap: OrmMap) {
|
|
54
|
+
return createAdapterFactory({
|
|
55
|
+
config: {
|
|
56
|
+
adapterId: 'fougere',
|
|
57
|
+
adapterName: 'Fougere Adapter',
|
|
58
|
+
usePlural: false,
|
|
59
|
+
supportsArrays: false,
|
|
60
|
+
supportsJSON: false,
|
|
61
|
+
// The ORM converts both ways now (`schema-sql/src/values.ts`), so better-auth
|
|
62
|
+
// can hand over the Dates and booleans its own types declare.
|
|
63
|
+
supportsDates: true,
|
|
64
|
+
supportsBooleans: true,
|
|
65
|
+
},
|
|
66
|
+
adapter: (): CustomAdapter => ({
|
|
67
|
+
create: async ({ model, data }: { model: string; data: Record<string, unknown> }) => {
|
|
68
|
+
const orm = getOrm(ormMap, model);
|
|
69
|
+
return (await orm.create(data)) as never;
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
findOne: async ({ model, where }: { model: string; where: CleanedWhere[] }) => {
|
|
73
|
+
const orm = getOrm(ormMap, model);
|
|
74
|
+
const criteria = whereToCriteria(where);
|
|
75
|
+
if (Object.keys(criteria).length === 1 && 'id' in criteria) {
|
|
76
|
+
const found = await orm.findById(criteria.id as string);
|
|
77
|
+
return (found ?? null) as never;
|
|
78
|
+
}
|
|
79
|
+
const found = await orm.findBy(criteria);
|
|
80
|
+
return (found ?? null) as never;
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
findMany: async ({
|
|
84
|
+
model,
|
|
85
|
+
where,
|
|
86
|
+
limit,
|
|
87
|
+
offset,
|
|
88
|
+
sortBy,
|
|
89
|
+
}: {
|
|
90
|
+
model: string;
|
|
91
|
+
where?: CleanedWhere[];
|
|
92
|
+
limit: number;
|
|
93
|
+
offset?: number;
|
|
94
|
+
sortBy?: { field: string; direction: 'asc' | 'desc' };
|
|
95
|
+
}) => {
|
|
96
|
+
const orm = getOrm(ormMap, model);
|
|
97
|
+
if (where && where.length > 0) {
|
|
98
|
+
const criteria = whereToCriteria(where);
|
|
99
|
+
const rows = await orm.findAllBy(criteria);
|
|
100
|
+
return applyClientSidePagination(rows, sortBy, offset, limit) as never;
|
|
101
|
+
}
|
|
102
|
+
const rows = await orm.list({
|
|
103
|
+
limit,
|
|
104
|
+
offset,
|
|
105
|
+
orderBy: sortBy?.field,
|
|
106
|
+
order: sortBy?.direction,
|
|
107
|
+
});
|
|
108
|
+
return rows as never;
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
count: async ({ model, where }: { model: string; where?: CleanedWhere[] }) => {
|
|
112
|
+
const orm = getOrm(ormMap, model);
|
|
113
|
+
if (where && where.length > 0) {
|
|
114
|
+
const criteria = whereToCriteria(where);
|
|
115
|
+
const rows = await orm.findAllBy(criteria);
|
|
116
|
+
return rows.length;
|
|
117
|
+
}
|
|
118
|
+
const rows = await orm.list({ count: true });
|
|
119
|
+
return rows.total ?? rows.length;
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
update: async <T>({ model, where, update }: { model: string; where: CleanedWhere[]; update: T }): Promise<T | null> => {
|
|
123
|
+
const orm = getOrm(ormMap, model);
|
|
124
|
+
const criteria = whereToCriteria(where);
|
|
125
|
+
const target = 'id' in criteria
|
|
126
|
+
? await orm.findById(criteria.id as string)
|
|
127
|
+
: await orm.findBy(criteria);
|
|
128
|
+
if (!target) return null;
|
|
129
|
+
return (await orm.update(target.id as string, update as Partial<Record<string, unknown>>)) as T;
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
updateMany: async ({ model, where, update }: { model: string; where: CleanedWhere[]; update: Record<string, unknown> }) => {
|
|
133
|
+
const orm = getOrm(ormMap, model);
|
|
134
|
+
const criteria = whereToCriteria(where);
|
|
135
|
+
const targets = await orm.findAllBy(criteria);
|
|
136
|
+
await Promise.all(targets.map((t) => orm.update(t.id as string, update)));
|
|
137
|
+
return targets.length;
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
delete: async ({ model, where }: { model: string; where: CleanedWhere[] }) => {
|
|
141
|
+
const orm = getOrm(ormMap, model);
|
|
142
|
+
const criteria = whereToCriteria(where);
|
|
143
|
+
const target = 'id' in criteria
|
|
144
|
+
? await orm.findById(criteria.id as string)
|
|
145
|
+
: await orm.findBy(criteria);
|
|
146
|
+
if (target) await orm.delete(target.id as string);
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
deleteMany: async ({ model, where }: { model: string; where: CleanedWhere[] }) => {
|
|
150
|
+
const orm = getOrm(ormMap, model);
|
|
151
|
+
const criteria = whereToCriteria(where);
|
|
152
|
+
const targets = await orm.findAllBy(criteria);
|
|
153
|
+
await Promise.all(targets.map((t) => orm.delete(t.id as string)));
|
|
154
|
+
return targets.length;
|
|
155
|
+
},
|
|
156
|
+
}),
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Augmented EntityOrm shape — the core interface doesn't expose findBy/findAllBy
|
|
162
|
+
* but SqlEntityOrm (the only impl today) does. Cast locally to use them.
|
|
163
|
+
*/
|
|
164
|
+
/**
|
|
165
|
+
* EntityOrm.findAllBy doesn't expose pagination/sort, so we apply them in JS
|
|
166
|
+
* after fetching the eq-filtered rows. Fine for auth volumes (orgs/sessions/accounts).
|
|
167
|
+
*/
|
|
168
|
+
function applyClientSidePagination(
|
|
169
|
+
rows: Record<string, unknown>[],
|
|
170
|
+
sortBy?: { field: string; direction: 'asc' | 'desc' },
|
|
171
|
+
offset?: number,
|
|
172
|
+
limit?: number,
|
|
173
|
+
): Record<string, unknown>[] {
|
|
174
|
+
let result = rows;
|
|
175
|
+
if (sortBy) {
|
|
176
|
+
const { field, direction } = sortBy;
|
|
177
|
+
result = [...result].sort((a, b) => {
|
|
178
|
+
const av = a[field], bv = b[field];
|
|
179
|
+
if (av == null && bv == null) return 0;
|
|
180
|
+
if (av == null) return -1;
|
|
181
|
+
if (bv == null) return 1;
|
|
182
|
+
const cmp = av < bv ? -1 : av > bv ? 1 : 0;
|
|
183
|
+
return direction === 'desc' ? -cmp : cmp;
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
if (offset !== undefined) result = result.slice(offset);
|
|
187
|
+
if (limit !== undefined) result = result.slice(0, limit);
|
|
188
|
+
return result;
|
|
189
|
+
}
|
package/src/entities.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { entity, primary, text, bool, date, created, ref, optional, type SchemaView } from '@fougere/schema';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Default User entity — shipped as a fallback. Apps should declare their own
|
|
5
|
+
* User entity in a frond and pass it via `auth.user` (with extra fields like roles).
|
|
6
|
+
*
|
|
7
|
+
* Field shape matches better-auth's expectations: name/email/emailVerified/image
|
|
8
|
+
* + standard timestamps.
|
|
9
|
+
*/
|
|
10
|
+
export class AuthUser extends entity({
|
|
11
|
+
id: primary(),
|
|
12
|
+
name: text(),
|
|
13
|
+
email: text(),
|
|
14
|
+
emailVerified: bool(),
|
|
15
|
+
image: optional(text()),
|
|
16
|
+
createdAt: created(),
|
|
17
|
+
updatedAt: created(),
|
|
18
|
+
}) {}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A `ref()` target is fixed at field-declaration time. Session and Account can't
|
|
22
|
+
* be static classes built once against this package's `AuthUser` — that would
|
|
23
|
+
* leave `userId` pointing at the wrong table whenever an app supplies its own
|
|
24
|
+
* User (`opts.user` in `betterAuth()`). `authEntities(User)` builds them fresh
|
|
25
|
+
* against whichever schema was actually resolved (the app's, or `AuthUser` as
|
|
26
|
+
* fallback), called from `betterAuth()` once `User` is known.
|
|
27
|
+
*
|
|
28
|
+
* `ref()` wants a live class — a construct signature plus `.name`, which
|
|
29
|
+
* `@fougere/adapter-sql`'s FK naming reads off the target — narrower than the
|
|
30
|
+
* `SchemaView` interface (`getFields()` only) this package's public options
|
|
31
|
+
* take, since `opts.user` may be any app's entity and `SchemaView` is the
|
|
32
|
+
* shape-only contract used to stay decoupled from a specific one. Every real
|
|
33
|
+
* entity satisfies both; the cast below only crosses that type-level gap, the
|
|
34
|
+
* same bridge `@fougere/schema` uses internally in `Bundle.toSchemas`
|
|
35
|
+
* (`schema as unknown as EntityConstructor`).
|
|
36
|
+
*/
|
|
37
|
+
type LiveEntity = abstract new (...args: any[]) => unknown;
|
|
38
|
+
|
|
39
|
+
export function authEntities(User: SchemaView): {
|
|
40
|
+
AuthSession: SchemaView;
|
|
41
|
+
AuthAccount: SchemaView;
|
|
42
|
+
} {
|
|
43
|
+
const target = User as unknown as LiveEntity;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Session entity — better-auth shape.
|
|
47
|
+
* `token` carries the opaque session secret (cookie value).
|
|
48
|
+
*/
|
|
49
|
+
class AuthSession extends entity({
|
|
50
|
+
id: primary(),
|
|
51
|
+
userId: ref(target),
|
|
52
|
+
token: text(),
|
|
53
|
+
expiresAt: date(),
|
|
54
|
+
ipAddress: optional(text()),
|
|
55
|
+
userAgent: optional(text()),
|
|
56
|
+
createdAt: created(),
|
|
57
|
+
updatedAt: created(),
|
|
58
|
+
}) {}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Account entity — better-auth shape (single PK, accountId/providerId pair,
|
|
62
|
+
* separate token columns instead of a JSON blob).
|
|
63
|
+
*/
|
|
64
|
+
class AuthAccount extends entity({
|
|
65
|
+
id: primary(),
|
|
66
|
+
accountId: text(),
|
|
67
|
+
providerId: text(),
|
|
68
|
+
userId: ref(target),
|
|
69
|
+
accessToken: optional(text()),
|
|
70
|
+
refreshToken: optional(text()),
|
|
71
|
+
idToken: optional(text()),
|
|
72
|
+
accessTokenExpiresAt: optional(date()),
|
|
73
|
+
refreshTokenExpiresAt: optional(date()),
|
|
74
|
+
scope: optional(text()),
|
|
75
|
+
password: optional(text()),
|
|
76
|
+
createdAt: created(),
|
|
77
|
+
updatedAt: created(),
|
|
78
|
+
}) {}
|
|
79
|
+
|
|
80
|
+
return { AuthSession, AuthAccount };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Default Verification entity — better-auth shape.
|
|
85
|
+
* Used for email verification, password reset, magic links, etc.
|
|
86
|
+
*/
|
|
87
|
+
export class AuthVerification extends entity({
|
|
88
|
+
id: primary(),
|
|
89
|
+
identifier: text(),
|
|
90
|
+
value: text(),
|
|
91
|
+
expiresAt: date(),
|
|
92
|
+
createdAt: created(),
|
|
93
|
+
updatedAt: created(),
|
|
94
|
+
}) {}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { betterAuth as betterAuthLib } from 'better-auth';
|
|
2
|
+
import { createId } from '@paralleldrive/cuid2';
|
|
3
|
+
import type { AuthConfig, AuthContext, AuthRuntime } from '@fougere/core';
|
|
4
|
+
import type { SchemaView } from '@fougere/schema';
|
|
5
|
+
import { AuthVerification, AuthUser, authEntities } from './entities.js';
|
|
6
|
+
import { fougereAdapter, type OrmMap } from './adapter.js';
|
|
7
|
+
import {
|
|
8
|
+
translateCredential,
|
|
9
|
+
translateSocial,
|
|
10
|
+
translatePlugins,
|
|
11
|
+
type FougereProviders,
|
|
12
|
+
} from './translate.js';
|
|
13
|
+
|
|
14
|
+
export { AuthUser, AuthVerification, authEntities } from './entities.js';
|
|
15
|
+
export type { FougereProviders, OIDCProviderConfig } from './translate.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Options accepted by the betterAuth() factory in fougere.config.ts.
|
|
19
|
+
*
|
|
20
|
+
* `user` should come from the app's own frond (roles, extra columns, its own
|
|
21
|
+
* table — Session/Account are built against it, see `authEntities`). Omitting
|
|
22
|
+
* it falls back to the package's `AuthUser`. Other entities default to the
|
|
23
|
+
* shapes shipped by this package and can be overridden too.
|
|
24
|
+
*/
|
|
25
|
+
export interface BetterAuthOptions {
|
|
26
|
+
user?: SchemaView;
|
|
27
|
+
secret: string;
|
|
28
|
+
baseUrl?: string;
|
|
29
|
+
basePath?: string;
|
|
30
|
+
providers?: FougereProviders;
|
|
31
|
+
trustedOrigins?: string[];
|
|
32
|
+
sessionTtl?: number;
|
|
33
|
+
session?: SchemaView;
|
|
34
|
+
account?: SchemaView;
|
|
35
|
+
verification?: SchemaView;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Factory used in fougere.config.ts:
|
|
40
|
+
*
|
|
41
|
+
* ```ts
|
|
42
|
+
* export default defineFougere({
|
|
43
|
+
* auth: betterAuth({ user: User, secret, providers: {...} }),
|
|
44
|
+
* });
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* Returns a lazy AuthConfig — the better-auth engine is only constructed when
|
|
48
|
+
* the core calls `create(ctx)` at boot, with the resolved db + ormFactory.
|
|
49
|
+
*/
|
|
50
|
+
export function betterAuth(opts: BetterAuthOptions): AuthConfig {
|
|
51
|
+
const userSchema = opts.user ?? AuthUser;
|
|
52
|
+
const { AuthSession, AuthAccount } = authEntities(userSchema);
|
|
53
|
+
const sessionSchema = opts.session ?? AuthSession;
|
|
54
|
+
const accountSchema = opts.account ?? AuthAccount;
|
|
55
|
+
const verificationSchema = opts.verification ?? AuthVerification;
|
|
56
|
+
const providers = opts.providers ?? {};
|
|
57
|
+
const basePath = opts.basePath ?? '/auth';
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
entities: {
|
|
61
|
+
user: userSchema,
|
|
62
|
+
session: sessionSchema,
|
|
63
|
+
account: accountSchema,
|
|
64
|
+
verification: verificationSchema,
|
|
65
|
+
},
|
|
66
|
+
create({ ormFactory }: AuthContext): AuthRuntime {
|
|
67
|
+
const ormMap: OrmMap = new Map([
|
|
68
|
+
['user', ormFactory(userSchema, 'user')],
|
|
69
|
+
['session', ormFactory(sessionSchema, 'session')],
|
|
70
|
+
['account', ormFactory(accountSchema, 'account')],
|
|
71
|
+
['verification', ormFactory(verificationSchema, 'verification')],
|
|
72
|
+
]);
|
|
73
|
+
|
|
74
|
+
const engine = betterAuthLib({
|
|
75
|
+
database: fougereAdapter(ormMap),
|
|
76
|
+
secret: opts.secret,
|
|
77
|
+
baseURL: opts.baseUrl,
|
|
78
|
+
basePath,
|
|
79
|
+
trustedOrigins: opts.trustedOrigins,
|
|
80
|
+
advanced: { database: { generateId: () => createId() } },
|
|
81
|
+
session: opts.sessionTtl ? { expiresIn: opts.sessionTtl / 1000 } : undefined,
|
|
82
|
+
emailAndPassword: translateCredential(providers),
|
|
83
|
+
socialProviders: translateSocial(providers),
|
|
84
|
+
plugins: translatePlugins(providers),
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
entities: {
|
|
89
|
+
user: userSchema,
|
|
90
|
+
session: sessionSchema,
|
|
91
|
+
account: accountSchema,
|
|
92
|
+
verification: verificationSchema,
|
|
93
|
+
},
|
|
94
|
+
orms: Object.fromEntries(ormMap),
|
|
95
|
+
handler: engine.handler,
|
|
96
|
+
api: engine.api as Record<string, unknown>,
|
|
97
|
+
basePath,
|
|
98
|
+
};
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
package/src/translate.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { genericOAuth } from 'better-auth/plugins';
|
|
2
|
+
import type { BetterAuthOptions, BetterAuthPlugin } from 'better-auth';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Fougere-side provider declaration. Mirrors what users write in fougere.config.ts.
|
|
6
|
+
*
|
|
7
|
+
* - `credential`: email + password (better-auth's emailAndPassword)
|
|
8
|
+
* - Standard OAuth keys (google, github, ...): become socialProviders
|
|
9
|
+
* - `oidc`: dictionary of OIDC providers, become genericOAuth plugin entries
|
|
10
|
+
*/
|
|
11
|
+
export interface FougereProviders {
|
|
12
|
+
credential?: {
|
|
13
|
+
minPasswordLength?: number;
|
|
14
|
+
maxPasswordLength?: number;
|
|
15
|
+
autoSignIn?: boolean;
|
|
16
|
+
};
|
|
17
|
+
google?: { clientId: string; clientSecret: string; scope?: string[] };
|
|
18
|
+
github?: { clientId: string; clientSecret: string; scope?: string[] };
|
|
19
|
+
facebook?: { clientId: string; clientSecret: string; scope?: string[] };
|
|
20
|
+
apple?: { clientId: string; clientSecret: string; scope?: string[] };
|
|
21
|
+
discord?: { clientId: string; clientSecret: string; scope?: string[] };
|
|
22
|
+
microsoft?: { clientId: string; clientSecret: string; scope?: string[] };
|
|
23
|
+
oidc?: Record<string, OIDCProviderConfig>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface OIDCProviderConfig {
|
|
27
|
+
/** Provider id used in the URL (e.g. /auth/oauth2/{id}/callback). Defaults to the dict key. */
|
|
28
|
+
id?: string;
|
|
29
|
+
/** OIDC issuer URL — used to derive the discovery URL. */
|
|
30
|
+
issuer: string;
|
|
31
|
+
clientId: string;
|
|
32
|
+
clientSecret: string;
|
|
33
|
+
scopes?: string[];
|
|
34
|
+
/** Pass-through for better-auth's genericOAuth provider config. */
|
|
35
|
+
redirectURI?: string;
|
|
36
|
+
responseType?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const SOCIAL_KEYS = new Set(['google', 'github', 'facebook', 'apple', 'discord', 'microsoft']);
|
|
40
|
+
|
|
41
|
+
export function translateCredential(providers?: FougereProviders): BetterAuthOptions['emailAndPassword'] {
|
|
42
|
+
const cred = providers?.credential;
|
|
43
|
+
if (!cred) return { enabled: false };
|
|
44
|
+
return {
|
|
45
|
+
enabled: true,
|
|
46
|
+
minPasswordLength: cred.minPasswordLength,
|
|
47
|
+
maxPasswordLength: cred.maxPasswordLength,
|
|
48
|
+
autoSignIn: cred.autoSignIn,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function translateSocial(providers?: FougereProviders): BetterAuthOptions['socialProviders'] {
|
|
53
|
+
if (!providers) return {};
|
|
54
|
+
const social: Record<string, unknown> = {};
|
|
55
|
+
for (const [key, value] of Object.entries(providers)) {
|
|
56
|
+
if (SOCIAL_KEYS.has(key)) social[key] = value;
|
|
57
|
+
}
|
|
58
|
+
return social as BetterAuthOptions['socialProviders'];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Build the plugin list from Fougere provider config.
|
|
63
|
+
* Currently produces:
|
|
64
|
+
* - `genericOAuth` plugin when `providers.oidc` is set (one entry per declared OIDC provider).
|
|
65
|
+
*/
|
|
66
|
+
export function translatePlugins(providers?: FougereProviders): BetterAuthPlugin[] {
|
|
67
|
+
const plugins: BetterAuthPlugin[] = [];
|
|
68
|
+
if (providers?.oidc) {
|
|
69
|
+
const config = Object.entries(providers.oidc).map(([key, oidc]) => ({
|
|
70
|
+
providerId: oidc.id ?? key,
|
|
71
|
+
discoveryUrl: oidc.issuer.replace(/\/$/, '') + '/.well-known/openid-configuration',
|
|
72
|
+
clientId: oidc.clientId,
|
|
73
|
+
clientSecret: oidc.clientSecret,
|
|
74
|
+
scopes: oidc.scopes ?? ['openid', 'email', 'profile'],
|
|
75
|
+
redirectURI: oidc.redirectURI,
|
|
76
|
+
responseType: oidc.responseType,
|
|
77
|
+
}));
|
|
78
|
+
plugins.push(genericOAuth({ config }));
|
|
79
|
+
}
|
|
80
|
+
return plugins;
|
|
81
|
+
}
|