create-scaffauth 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 +82 -0
- package/dist/index.js +1050 -0
- package/dist/index.js.map +1 -0
- package/dist/templates/express/drizzle-mysql/.env.example.hbs +39 -0
- package/dist/templates/express/drizzle-mysql/README.md.hbs +78 -0
- package/dist/templates/express/drizzle-mysql/drizzle/db.ts +8 -0
- package/dist/templates/express/drizzle-mysql/drizzle/migrate.ts +22 -0
- package/dist/templates/express/drizzle-mysql/drizzle/schema.ts +58 -0
- package/dist/templates/express/drizzle-mysql/drizzle.config.ts +10 -0
- package/dist/templates/express/drizzle-mysql/package.json.hbs +36 -0
- package/dist/templates/express/drizzle-mysql/src/auth.ts.hbs +114 -0
- package/dist/templates/express/drizzle-mysql/src/index.ts +28 -0
- package/dist/templates/express/drizzle-mysql/tsconfig.json +19 -0
- package/dist/templates/express/drizzle-postgres/.env.example.hbs +39 -0
- package/dist/templates/express/drizzle-postgres/README.md.hbs +78 -0
- package/dist/templates/express/drizzle-postgres/drizzle/db.ts +8 -0
- package/dist/templates/express/drizzle-postgres/drizzle/migrate.ts +22 -0
- package/dist/templates/express/drizzle-postgres/drizzle/schema.ts +57 -0
- package/dist/templates/express/drizzle-postgres/drizzle.config.ts +10 -0
- package/dist/templates/express/drizzle-postgres/package.json.hbs +37 -0
- package/dist/templates/express/drizzle-postgres/src/auth.ts.hbs +114 -0
- package/dist/templates/express/drizzle-postgres/src/index.ts +28 -0
- package/dist/templates/express/drizzle-postgres/tsconfig.json +19 -0
- package/dist/templates/express/drizzle-sqlite/.env.example.hbs +39 -0
- package/dist/templates/express/drizzle-sqlite/README.md.hbs +78 -0
- package/dist/templates/express/drizzle-sqlite/drizzle/db.ts +6 -0
- package/dist/templates/express/drizzle-sqlite/drizzle/migrate.ts +12 -0
- package/dist/templates/express/drizzle-sqlite/drizzle/schema.ts +55 -0
- package/dist/templates/express/drizzle-sqlite/drizzle.config.ts +10 -0
- package/dist/templates/express/drizzle-sqlite/package.json.hbs +37 -0
- package/dist/templates/express/drizzle-sqlite/src/auth.ts.hbs +114 -0
- package/dist/templates/express/drizzle-sqlite/src/index.ts +28 -0
- package/dist/templates/express/drizzle-sqlite/tsconfig.json +19 -0
- package/dist/templates/express/kysely-mysql/.env.example.hbs +39 -0
- package/dist/templates/express/kysely-mysql/README.md.hbs +75 -0
- package/dist/templates/express/kysely-mysql/db/db.ts +11 -0
- package/dist/templates/express/kysely-mysql/db/migrate.ts +77 -0
- package/dist/templates/express/kysely-mysql/db/types.ts +54 -0
- package/dist/templates/express/kysely-mysql/package.json.hbs +32 -0
- package/dist/templates/express/kysely-mysql/src/auth.ts.hbs +114 -0
- package/dist/templates/express/kysely-mysql/src/index.ts +28 -0
- package/dist/templates/express/kysely-mysql/tsconfig.json +19 -0
- package/dist/templates/express/kysely-postgres/.env.example.hbs +39 -0
- package/dist/templates/express/kysely-postgres/README.md.hbs +75 -0
- package/dist/templates/express/kysely-postgres/db/db.ts +11 -0
- package/dist/templates/express/kysely-postgres/db/migrate.ts +77 -0
- package/dist/templates/express/kysely-postgres/db/types.ts +54 -0
- package/dist/templates/express/kysely-postgres/package.json.hbs +33 -0
- package/dist/templates/express/kysely-postgres/src/auth.ts.hbs +114 -0
- package/dist/templates/express/kysely-postgres/src/index.ts +28 -0
- package/dist/templates/express/kysely-postgres/tsconfig.json +19 -0
- package/dist/templates/express/kysely-sqlite/.env.example.hbs +39 -0
- package/dist/templates/express/kysely-sqlite/README.md.hbs +75 -0
- package/dist/templates/express/kysely-sqlite/db/db.ts +9 -0
- package/dist/templates/express/kysely-sqlite/db/migrate.ts +75 -0
- package/dist/templates/express/kysely-sqlite/db/types.ts +54 -0
- package/dist/templates/express/kysely-sqlite/package.json.hbs +33 -0
- package/dist/templates/express/kysely-sqlite/src/auth.ts.hbs +114 -0
- package/dist/templates/express/kysely-sqlite/src/index.ts +28 -0
- package/dist/templates/express/kysely-sqlite/tsconfig.json +19 -0
- package/dist/templates/express/prisma-mysql/.env.example.hbs +39 -0
- package/dist/templates/express/prisma-mysql/README.md.hbs +79 -0
- package/dist/templates/express/prisma-mysql/package.json.hbs +35 -0
- package/dist/templates/express/prisma-mysql/prisma/schema.prisma +66 -0
- package/dist/templates/express/prisma-mysql/src/auth.ts.hbs +114 -0
- package/dist/templates/express/prisma-mysql/src/db.ts +3 -0
- package/dist/templates/express/prisma-mysql/src/index.ts +28 -0
- package/dist/templates/express/prisma-mysql/tsconfig.json +19 -0
- package/dist/templates/express/prisma-postgres/.env.example.hbs +39 -0
- package/dist/templates/express/prisma-postgres/README.md.hbs +79 -0
- package/dist/templates/express/prisma-postgres/package.json.hbs +35 -0
- package/dist/templates/express/prisma-postgres/prisma/schema.prisma +66 -0
- package/dist/templates/express/prisma-postgres/src/auth.ts.hbs +114 -0
- package/dist/templates/express/prisma-postgres/src/db.ts +3 -0
- package/dist/templates/express/prisma-postgres/src/index.ts +28 -0
- package/dist/templates/express/prisma-postgres/tsconfig.json +19 -0
- package/dist/templates/express/prisma-sqlite/.env.example.hbs +39 -0
- package/dist/templates/express/prisma-sqlite/README.md.hbs +79 -0
- package/dist/templates/express/prisma-sqlite/package.json.hbs +35 -0
- package/dist/templates/express/prisma-sqlite/prisma/schema.prisma +66 -0
- package/dist/templates/express/prisma-sqlite/src/auth.ts.hbs +114 -0
- package/dist/templates/express/prisma-sqlite/src/db.ts +3 -0
- package/dist/templates/express/prisma-sqlite/src/index.ts +28 -0
- package/dist/templates/express/prisma-sqlite/tsconfig.json +19 -0
- package/dist/templates/fastify/drizzle-mysql/.env.example.hbs +39 -0
- package/dist/templates/fastify/drizzle-mysql/README.md.hbs +78 -0
- package/dist/templates/fastify/drizzle-mysql/drizzle/db.ts +8 -0
- package/dist/templates/fastify/drizzle-mysql/drizzle/migrate.ts +22 -0
- package/dist/templates/fastify/drizzle-mysql/drizzle/schema.ts +58 -0
- package/dist/templates/fastify/drizzle-mysql/drizzle.config.ts +10 -0
- package/dist/templates/fastify/drizzle-mysql/package.json.hbs +34 -0
- package/dist/templates/fastify/drizzle-mysql/src/auth.ts.hbs +114 -0
- package/dist/templates/fastify/drizzle-mysql/src/index.ts +34 -0
- package/dist/templates/fastify/drizzle-mysql/tsconfig.json +19 -0
- package/dist/templates/fastify/drizzle-postgres/.env.example.hbs +39 -0
- package/dist/templates/fastify/drizzle-postgres/README.md.hbs +78 -0
- package/dist/templates/fastify/drizzle-postgres/drizzle/db.ts +8 -0
- package/dist/templates/fastify/drizzle-postgres/drizzle/migrate.ts +22 -0
- package/dist/templates/fastify/drizzle-postgres/drizzle/schema.ts +57 -0
- package/dist/templates/fastify/drizzle-postgres/drizzle.config.ts +10 -0
- package/dist/templates/fastify/drizzle-postgres/package.json.hbs +35 -0
- package/dist/templates/fastify/drizzle-postgres/src/auth.ts.hbs +114 -0
- package/dist/templates/fastify/drizzle-postgres/src/index.ts +34 -0
- package/dist/templates/fastify/drizzle-postgres/tsconfig.json +19 -0
- package/dist/templates/fastify/drizzle-sqlite/.env.example.hbs +39 -0
- package/dist/templates/fastify/drizzle-sqlite/README.md.hbs +78 -0
- package/dist/templates/fastify/drizzle-sqlite/drizzle/db.ts +6 -0
- package/dist/templates/fastify/drizzle-sqlite/drizzle/migrate.ts +12 -0
- package/dist/templates/fastify/drizzle-sqlite/drizzle/schema.ts +55 -0
- package/dist/templates/fastify/drizzle-sqlite/drizzle.config.ts +10 -0
- package/dist/templates/fastify/drizzle-sqlite/package.json.hbs +35 -0
- package/dist/templates/fastify/drizzle-sqlite/src/auth.ts.hbs +114 -0
- package/dist/templates/fastify/drizzle-sqlite/src/index.ts +34 -0
- package/dist/templates/fastify/drizzle-sqlite/tsconfig.json +19 -0
- package/dist/templates/fastify/kysely-mysql/.env.example.hbs +39 -0
- package/dist/templates/fastify/kysely-mysql/README.md.hbs +75 -0
- package/dist/templates/fastify/kysely-mysql/db/db.ts +11 -0
- package/dist/templates/fastify/kysely-mysql/db/migrate.ts +77 -0
- package/dist/templates/fastify/kysely-mysql/db/types.ts +54 -0
- package/dist/templates/fastify/kysely-mysql/package.json.hbs +30 -0
- package/dist/templates/fastify/kysely-mysql/src/auth.ts.hbs +114 -0
- package/dist/templates/fastify/kysely-mysql/src/index.ts +34 -0
- package/dist/templates/fastify/kysely-mysql/tsconfig.json +19 -0
- package/dist/templates/fastify/kysely-postgres/.env.example.hbs +39 -0
- package/dist/templates/fastify/kysely-postgres/README.md.hbs +75 -0
- package/dist/templates/fastify/kysely-postgres/db/db.ts +11 -0
- package/dist/templates/fastify/kysely-postgres/db/migrate.ts +77 -0
- package/dist/templates/fastify/kysely-postgres/db/types.ts +54 -0
- package/dist/templates/fastify/kysely-postgres/package.json.hbs +31 -0
- package/dist/templates/fastify/kysely-postgres/src/auth.ts.hbs +114 -0
- package/dist/templates/fastify/kysely-postgres/src/index.ts +34 -0
- package/dist/templates/fastify/kysely-postgres/tsconfig.json +19 -0
- package/dist/templates/fastify/kysely-sqlite/.env.example.hbs +39 -0
- package/dist/templates/fastify/kysely-sqlite/README.md.hbs +75 -0
- package/dist/templates/fastify/kysely-sqlite/db/db.ts +9 -0
- package/dist/templates/fastify/kysely-sqlite/db/migrate.ts +75 -0
- package/dist/templates/fastify/kysely-sqlite/db/types.ts +54 -0
- package/dist/templates/fastify/kysely-sqlite/package.json.hbs +31 -0
- package/dist/templates/fastify/kysely-sqlite/src/auth.ts.hbs +114 -0
- package/dist/templates/fastify/kysely-sqlite/src/index.ts +34 -0
- package/dist/templates/fastify/kysely-sqlite/tsconfig.json +19 -0
- package/dist/templates/fastify/prisma-mysql/.env.example.hbs +39 -0
- package/dist/templates/fastify/prisma-mysql/README.md.hbs +79 -0
- package/dist/templates/fastify/prisma-mysql/package.json.hbs +33 -0
- package/dist/templates/fastify/prisma-mysql/prisma/schema.prisma +66 -0
- package/dist/templates/fastify/prisma-mysql/src/auth.ts.hbs +114 -0
- package/dist/templates/fastify/prisma-mysql/src/db.ts +3 -0
- package/dist/templates/fastify/prisma-mysql/src/index.ts +34 -0
- package/dist/templates/fastify/prisma-mysql/tsconfig.json +19 -0
- package/dist/templates/fastify/prisma-postgres/.env.example.hbs +39 -0
- package/dist/templates/fastify/prisma-postgres/README.md.hbs +79 -0
- package/dist/templates/fastify/prisma-postgres/package.json.hbs +33 -0
- package/dist/templates/fastify/prisma-postgres/prisma/schema.prisma +66 -0
- package/dist/templates/fastify/prisma-postgres/src/auth.ts.hbs +114 -0
- package/dist/templates/fastify/prisma-postgres/src/db.ts +3 -0
- package/dist/templates/fastify/prisma-postgres/src/index.ts +34 -0
- package/dist/templates/fastify/prisma-postgres/tsconfig.json +19 -0
- package/dist/templates/fastify/prisma-sqlite/.env.example.hbs +39 -0
- package/dist/templates/fastify/prisma-sqlite/README.md.hbs +79 -0
- package/dist/templates/fastify/prisma-sqlite/package.json.hbs +33 -0
- package/dist/templates/fastify/prisma-sqlite/prisma/schema.prisma +66 -0
- package/dist/templates/fastify/prisma-sqlite/src/auth.ts.hbs +114 -0
- package/dist/templates/fastify/prisma-sqlite/src/db.ts +3 -0
- package/dist/templates/fastify/prisma-sqlite/src/index.ts +34 -0
- package/dist/templates/fastify/prisma-sqlite/tsconfig.json +19 -0
- package/dist/templates/hono/drizzle-mysql/.env.example.hbs +39 -0
- package/dist/templates/hono/drizzle-mysql/README.md.hbs +85 -0
- package/dist/templates/hono/drizzle-mysql/drizzle/db.ts +8 -0
- package/dist/templates/hono/drizzle-mysql/drizzle/migrate.ts +22 -0
- package/dist/templates/hono/drizzle-mysql/drizzle/schema.ts +58 -0
- package/dist/templates/hono/drizzle-mysql/drizzle.config.ts +10 -0
- package/dist/templates/hono/drizzle-mysql/package.json.hbs +33 -0
- package/dist/templates/hono/drizzle-mysql/src/auth.ts.hbs +114 -0
- package/dist/templates/hono/drizzle-mysql/src/index.ts +35 -0
- package/dist/templates/hono/drizzle-mysql/tsconfig.json +19 -0
- package/dist/templates/hono/drizzle-postgres/.env.example.hbs +39 -0
- package/dist/templates/hono/drizzle-postgres/README.md.hbs +85 -0
- package/dist/templates/hono/drizzle-postgres/drizzle/db.ts +8 -0
- package/dist/templates/hono/drizzle-postgres/drizzle/migrate.ts +22 -0
- package/dist/templates/hono/drizzle-postgres/drizzle/schema.ts +57 -0
- package/dist/templates/hono/drizzle-postgres/drizzle.config.ts +10 -0
- package/dist/templates/hono/drizzle-postgres/package.json.hbs +34 -0
- package/dist/templates/hono/drizzle-postgres/src/auth.ts.hbs +114 -0
- package/dist/templates/hono/drizzle-postgres/src/index.ts +35 -0
- package/dist/templates/hono/drizzle-postgres/tsconfig.json +19 -0
- package/dist/templates/hono/drizzle-sqlite/.env.example.hbs +39 -0
- package/dist/templates/hono/drizzle-sqlite/README.md.hbs +85 -0
- package/dist/templates/hono/drizzle-sqlite/drizzle/db.ts +6 -0
- package/dist/templates/hono/drizzle-sqlite/drizzle/migrate.ts +12 -0
- package/dist/templates/hono/drizzle-sqlite/drizzle/schema.ts +55 -0
- package/dist/templates/hono/drizzle-sqlite/drizzle.config.ts +10 -0
- package/dist/templates/hono/drizzle-sqlite/package.json.hbs +34 -0
- package/dist/templates/hono/drizzle-sqlite/src/auth.ts.hbs +114 -0
- package/dist/templates/hono/drizzle-sqlite/src/index.ts +35 -0
- package/dist/templates/hono/drizzle-sqlite/tsconfig.json +19 -0
- package/dist/templates/hono/kysely-mysql/.env.example.hbs +39 -0
- package/dist/templates/hono/kysely-mysql/README.md.hbs +75 -0
- package/dist/templates/hono/kysely-mysql/db/db.ts +11 -0
- package/dist/templates/hono/kysely-mysql/db/migrate.ts +77 -0
- package/dist/templates/hono/kysely-mysql/db/types.ts +54 -0
- package/dist/templates/hono/kysely-mysql/package.json.hbs +29 -0
- package/dist/templates/hono/kysely-mysql/src/auth.ts.hbs +114 -0
- package/dist/templates/hono/kysely-mysql/src/index.ts +35 -0
- package/dist/templates/hono/kysely-mysql/tsconfig.json +19 -0
- package/dist/templates/hono/kysely-postgres/.env.example.hbs +39 -0
- package/dist/templates/hono/kysely-postgres/README.md.hbs +75 -0
- package/dist/templates/hono/kysely-postgres/db/db.ts +11 -0
- package/dist/templates/hono/kysely-postgres/db/migrate.ts +77 -0
- package/dist/templates/hono/kysely-postgres/db/types.ts +54 -0
- package/dist/templates/hono/kysely-postgres/package.json.hbs +30 -0
- package/dist/templates/hono/kysely-postgres/src/auth.ts.hbs +114 -0
- package/dist/templates/hono/kysely-postgres/src/index.ts +35 -0
- package/dist/templates/hono/kysely-postgres/tsconfig.json +19 -0
- package/dist/templates/hono/kysely-sqlite/.env.example.hbs +39 -0
- package/dist/templates/hono/kysely-sqlite/README.md.hbs +75 -0
- package/dist/templates/hono/kysely-sqlite/db/db.ts +9 -0
- package/dist/templates/hono/kysely-sqlite/db/migrate.ts +75 -0
- package/dist/templates/hono/kysely-sqlite/db/types.ts +54 -0
- package/dist/templates/hono/kysely-sqlite/package.json.hbs +30 -0
- package/dist/templates/hono/kysely-sqlite/src/auth.ts.hbs +114 -0
- package/dist/templates/hono/kysely-sqlite/src/index.ts +35 -0
- package/dist/templates/hono/kysely-sqlite/tsconfig.json +19 -0
- package/dist/templates/hono/prisma-mysql/.env.example.hbs +39 -0
- package/dist/templates/hono/prisma-mysql/README.md.hbs +79 -0
- package/dist/templates/hono/prisma-mysql/package.json.hbs +32 -0
- package/dist/templates/hono/prisma-mysql/prisma/schema.prisma +66 -0
- package/dist/templates/hono/prisma-mysql/src/auth.ts.hbs +114 -0
- package/dist/templates/hono/prisma-mysql/src/db.ts +3 -0
- package/dist/templates/hono/prisma-mysql/src/index.ts +35 -0
- package/dist/templates/hono/prisma-mysql/tsconfig.json +19 -0
- package/dist/templates/hono/prisma-postgres/.env.example.hbs +39 -0
- package/dist/templates/hono/prisma-postgres/README.md.hbs +79 -0
- package/dist/templates/hono/prisma-postgres/package.json.hbs +32 -0
- package/dist/templates/hono/prisma-postgres/prisma/schema.prisma +66 -0
- package/dist/templates/hono/prisma-postgres/src/auth.ts.hbs +114 -0
- package/dist/templates/hono/prisma-postgres/src/db.ts +3 -0
- package/dist/templates/hono/prisma-postgres/src/index.ts +35 -0
- package/dist/templates/hono/prisma-postgres/tsconfig.json +19 -0
- package/dist/templates/hono/prisma-sqlite/.env.example.hbs +39 -0
- package/dist/templates/hono/prisma-sqlite/README.md.hbs +79 -0
- package/dist/templates/hono/prisma-sqlite/package.json.hbs +32 -0
- package/dist/templates/hono/prisma-sqlite/prisma/schema.prisma +66 -0
- package/dist/templates/hono/prisma-sqlite/src/auth.ts.hbs +114 -0
- package/dist/templates/hono/prisma-sqlite/src/db.ts +3 -0
- package/dist/templates/hono/prisma-sqlite/src/index.ts +35 -0
- package/dist/templates/hono/prisma-sqlite/tsconfig.json +19 -0
- package/package.json +71 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Generated, ColumnType } from "kysely";
|
|
2
|
+
|
|
3
|
+
export interface Database {
|
|
4
|
+
user: UserTable;
|
|
5
|
+
session: SessionTable;
|
|
6
|
+
account: AccountTable;
|
|
7
|
+
verification: VerificationTable;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface UserTable {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
email: string;
|
|
14
|
+
emailVerified: boolean;
|
|
15
|
+
image: string | null;
|
|
16
|
+
createdAt: Generated<Date>;
|
|
17
|
+
updatedAt: Generated<Date>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface SessionTable {
|
|
21
|
+
id: string;
|
|
22
|
+
expiresAt: Date;
|
|
23
|
+
token: string;
|
|
24
|
+
createdAt: Generated<Date>;
|
|
25
|
+
updatedAt: Generated<Date>;
|
|
26
|
+
ipAddress: string | null;
|
|
27
|
+
userAgent: string | null;
|
|
28
|
+
userId: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface AccountTable {
|
|
32
|
+
id: string;
|
|
33
|
+
accountId: string;
|
|
34
|
+
providerId: string;
|
|
35
|
+
userId: string;
|
|
36
|
+
accessToken: string | null;
|
|
37
|
+
refreshToken: string | null;
|
|
38
|
+
idToken: string | null;
|
|
39
|
+
accessTokenExpiresAt: Date | null;
|
|
40
|
+
refreshTokenExpiresAt: Date | null;
|
|
41
|
+
scope: string | null;
|
|
42
|
+
password: string | null;
|
|
43
|
+
createdAt: Generated<Date>;
|
|
44
|
+
updatedAt: Generated<Date>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface VerificationTable {
|
|
48
|
+
id: string;
|
|
49
|
+
identifier: string;
|
|
50
|
+
value: string;
|
|
51
|
+
expiresAt: Date;
|
|
52
|
+
createdAt: Generated<Date>;
|
|
53
|
+
updatedAt: Generated<Date>;
|
|
54
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{projectName}}",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "tsx watch src/index.ts",
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"start": "node dist/index.js",
|
|
10
|
+
"db:migrate": "tsx db/migrate.ts"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"better-auth": "^1.2.0",
|
|
14
|
+
"hono": "^4.7.0",
|
|
15
|
+
"kysely": "^0.27.0",
|
|
16
|
+
"mysql2": "^3.11.0"
|
|
17
|
+
{{#if (eq emailProvider "resend")}},
|
|
18
|
+
"resend": "^4.0.0"{{/if}}{{#if (eq emailProvider "sendgrid")}},
|
|
19
|
+
"@sendgrid/mail": "^8.1.0"{{/if}}{{#if (eq emailProvider "smtp")}},
|
|
20
|
+
"nodemailer": "^6.9.0"{{/if}}
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/node": "^22.13.0",
|
|
24
|
+
"tsx": "^4.19.0",
|
|
25
|
+
"typescript": "^5.7.0"
|
|
26
|
+
{{#if (eq emailProvider "smtp")}},
|
|
27
|
+
"@types/nodemailer": "^6.4.0"{{/if}}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { betterAuth } from "better-auth";
|
|
2
|
+
import { kyselyAdapter } from "better-auth/adapters/kysely";
|
|
3
|
+
import { db } from "../db/db";
|
|
4
|
+
{{#if twoFactor}}
|
|
5
|
+
import { twoFactor } from "better-auth/plugins";
|
|
6
|
+
{{/if}}
|
|
7
|
+
{{#if rbac}}
|
|
8
|
+
import { admin } from "better-auth/plugins";
|
|
9
|
+
{{/if}}
|
|
10
|
+
{{#if (eq emailProvider "resend")}}
|
|
11
|
+
import { Resend } from "resend";
|
|
12
|
+
|
|
13
|
+
const resend = new Resend(process.env.RESEND_API_KEY);
|
|
14
|
+
{{/if}}
|
|
15
|
+
{{#if (eq emailProvider "sendgrid")}}
|
|
16
|
+
import sgMail from "@sendgrid/mail";
|
|
17
|
+
|
|
18
|
+
sgMail.setApiKey(process.env.SENDGRID_API_KEY!);
|
|
19
|
+
{{/if}}
|
|
20
|
+
{{#if (eq emailProvider "smtp")}}
|
|
21
|
+
import nodemailer from "nodemailer";
|
|
22
|
+
|
|
23
|
+
const transporter = nodemailer.createTransport({
|
|
24
|
+
host: process.env.SMTP_HOST,
|
|
25
|
+
port: Number(process.env.SMTP_PORT) || 587,
|
|
26
|
+
auth: {
|
|
27
|
+
user: process.env.SMTP_USER,
|
|
28
|
+
pass: process.env.SMTP_PASS,
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
{{/if}}
|
|
32
|
+
|
|
33
|
+
export const auth = betterAuth({
|
|
34
|
+
database: kyselyAdapter(db, {
|
|
35
|
+
type: "mysql",
|
|
36
|
+
}),
|
|
37
|
+
emailAndPassword: {
|
|
38
|
+
enabled: true,
|
|
39
|
+
{{#if emailProvider}}
|
|
40
|
+
requireEmailVerification: true,
|
|
41
|
+
sendResetPassword: async ({ user, url }) => {
|
|
42
|
+
await sendEmail(user.email, "Reset your password", `<a href="${url}">Reset password</a>`);
|
|
43
|
+
},
|
|
44
|
+
{{/if}}
|
|
45
|
+
},
|
|
46
|
+
session: {
|
|
47
|
+
expiresIn: {{sessionExpiresIn}},
|
|
48
|
+
updateAge: {{sessionUpdateAge}},
|
|
49
|
+
cookieCache: {
|
|
50
|
+
enabled: {{sessionCookieCacheEnabled}},
|
|
51
|
+
maxAge: {{sessionCookieCacheMaxAge}},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
{{#if emailProvider}}
|
|
55
|
+
emailVerification: {
|
|
56
|
+
sendOnSignUp: true,
|
|
57
|
+
sendVerificationEmail: async ({ user, url }) => {
|
|
58
|
+
await sendEmail(user.email, "Verify your email", `<a href="${url}">Verify email</a>`);
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
{{/if}}
|
|
62
|
+
{{#if providers.length}}
|
|
63
|
+
socialProviders: {
|
|
64
|
+
{{#each providers}}
|
|
65
|
+
{{this}}: {
|
|
66
|
+
clientId: process.env.{{uppercase this}}_CLIENT_ID!,
|
|
67
|
+
clientSecret: process.env.{{uppercase this}}_CLIENT_SECRET!,
|
|
68
|
+
},
|
|
69
|
+
{{/each}}
|
|
70
|
+
},
|
|
71
|
+
{{/if}}
|
|
72
|
+
{{#if (or twoFactor rbac)}}
|
|
73
|
+
plugins: [
|
|
74
|
+
{{#if twoFactor}}
|
|
75
|
+
twoFactor(),
|
|
76
|
+
{{/if}}
|
|
77
|
+
{{#if rbac}}
|
|
78
|
+
admin({
|
|
79
|
+
defaultRole: "user",
|
|
80
|
+
}),
|
|
81
|
+
{{/if}}
|
|
82
|
+
],
|
|
83
|
+
{{/if}}
|
|
84
|
+
trustedOrigins: [process.env.CORS_ORIGIN || "http://localhost:3001"],
|
|
85
|
+
});
|
|
86
|
+
{{#if emailProvider}}
|
|
87
|
+
|
|
88
|
+
async function sendEmail(to: string, subject: string, html: string) {
|
|
89
|
+
{{#if (eq emailProvider "resend")}}
|
|
90
|
+
await resend.emails.send({
|
|
91
|
+
from: process.env.EMAIL_FROM || "noreply@example.com",
|
|
92
|
+
to,
|
|
93
|
+
subject,
|
|
94
|
+
html,
|
|
95
|
+
});
|
|
96
|
+
{{/if}}
|
|
97
|
+
{{#if (eq emailProvider "sendgrid")}}
|
|
98
|
+
await sgMail.send({
|
|
99
|
+
from: process.env.EMAIL_FROM || "noreply@example.com",
|
|
100
|
+
to,
|
|
101
|
+
subject,
|
|
102
|
+
html,
|
|
103
|
+
});
|
|
104
|
+
{{/if}}
|
|
105
|
+
{{#if (eq emailProvider "smtp")}}
|
|
106
|
+
await transporter.sendMail({
|
|
107
|
+
from: process.env.EMAIL_FROM || "noreply@example.com",
|
|
108
|
+
to,
|
|
109
|
+
subject,
|
|
110
|
+
html,
|
|
111
|
+
});
|
|
112
|
+
{{/if}}
|
|
113
|
+
}
|
|
114
|
+
{{/if}}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { cors } from "hono/cors";
|
|
3
|
+
import { logger } from "hono/logger";
|
|
4
|
+
import { auth } from "./auth";
|
|
5
|
+
|
|
6
|
+
const app = new Hono();
|
|
7
|
+
|
|
8
|
+
// Middleware
|
|
9
|
+
app.use("*", logger());
|
|
10
|
+
app.use(
|
|
11
|
+
"*",
|
|
12
|
+
cors({
|
|
13
|
+
origin: process.env.CORS_ORIGIN || "http://localhost:3001",
|
|
14
|
+
credentials: true,
|
|
15
|
+
}),
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
// Mount Better Auth handler
|
|
19
|
+
app.on(["POST", "GET"], "/api/auth/**", (c) => {
|
|
20
|
+
return auth.handler(c.req.raw);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Health check
|
|
24
|
+
app.get("/", (c) => {
|
|
25
|
+
return c.json({ status: "ok", message: "Auth backend is running" });
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Start server
|
|
29
|
+
const port = Number(process.env.PORT) || 3000;
|
|
30
|
+
console.log(`Server running on http://localhost:${port}`);
|
|
31
|
+
|
|
32
|
+
export default {
|
|
33
|
+
port,
|
|
34
|
+
fetch: app.fetch,
|
|
35
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"outDir": "dist",
|
|
8
|
+
"rootDir": ".",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"declaration": true,
|
|
15
|
+
"sourceMap": true
|
|
16
|
+
},
|
|
17
|
+
"include": ["src/**/*.ts", "drizzle/**/*.ts"],
|
|
18
|
+
"exclude": ["node_modules", "dist"]
|
|
19
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Database
|
|
2
|
+
DATABASE_URL=postgresql://user:password@localhost:5432/{{projectName}}
|
|
3
|
+
|
|
4
|
+
# Better Auth
|
|
5
|
+
BETTER_AUTH_SECRET={{authSecret}}
|
|
6
|
+
BETTER_AUTH_URL=http://localhost:3000
|
|
7
|
+
|
|
8
|
+
# CORS
|
|
9
|
+
CORS_ORIGIN=http://localhost:3001
|
|
10
|
+
|
|
11
|
+
# Server
|
|
12
|
+
PORT=3000
|
|
13
|
+
{{#each providers}}
|
|
14
|
+
|
|
15
|
+
# {{uppercase this}} OAuth
|
|
16
|
+
{{uppercase this}}_CLIENT_ID=
|
|
17
|
+
{{uppercase this}}_CLIENT_SECRET=
|
|
18
|
+
{{/each}}
|
|
19
|
+
{{#if (eq emailProvider "resend")}}
|
|
20
|
+
|
|
21
|
+
# Email (Resend)
|
|
22
|
+
RESEND_API_KEY=
|
|
23
|
+
EMAIL_FROM=noreply@example.com
|
|
24
|
+
{{/if}}
|
|
25
|
+
{{#if (eq emailProvider "sendgrid")}}
|
|
26
|
+
|
|
27
|
+
# Email (SendGrid)
|
|
28
|
+
SENDGRID_API_KEY=
|
|
29
|
+
EMAIL_FROM=noreply@example.com
|
|
30
|
+
{{/if}}
|
|
31
|
+
{{#if (eq emailProvider "smtp")}}
|
|
32
|
+
|
|
33
|
+
# Email (SMTP)
|
|
34
|
+
SMTP_HOST=smtp.example.com
|
|
35
|
+
SMTP_PORT=587
|
|
36
|
+
SMTP_USER=
|
|
37
|
+
SMTP_PASS=
|
|
38
|
+
EMAIL_FROM=noreply@example.com
|
|
39
|
+
{{/if}}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# {{projectName}}
|
|
2
|
+
|
|
3
|
+
Authentication backend powered by [Better Auth](https://better-auth.com), built with Hono + Kysely + PostgreSQL.
|
|
4
|
+
|
|
5
|
+
Generated with [Scaffauth](https://scaffauth.xyz).
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Install dependencies
|
|
11
|
+
npm install
|
|
12
|
+
|
|
13
|
+
# Copy environment variables
|
|
14
|
+
cp .env.example .env
|
|
15
|
+
|
|
16
|
+
# Update DATABASE_URL in .env with your PostgreSQL connection string
|
|
17
|
+
|
|
18
|
+
# Run migrations
|
|
19
|
+
npm run db:migrate
|
|
20
|
+
|
|
21
|
+
# Start development server
|
|
22
|
+
npm run dev
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Your auth backend will be running at `http://localhost:3000`.
|
|
26
|
+
|
|
27
|
+
## API Endpoints
|
|
28
|
+
|
|
29
|
+
Better Auth provides these endpoints automatically:
|
|
30
|
+
|
|
31
|
+
| Method | Endpoint | Description |
|
|
32
|
+
|--------|----------|-------------|
|
|
33
|
+
| POST | `/api/auth/sign-up/email` | Register with email/password |
|
|
34
|
+
| POST | `/api/auth/sign-in/email` | Sign in with email/password |
|
|
35
|
+
| POST | `/api/auth/sign-out` | Sign out |
|
|
36
|
+
| GET | `/api/auth/session` | Get current session |
|
|
37
|
+
{{#each providers}}
|
|
38
|
+
| GET | `/api/auth/sign-in/social` | Sign in with {{this}} |
|
|
39
|
+
{{/each}}
|
|
40
|
+
|
|
41
|
+
## Environment Variables
|
|
42
|
+
|
|
43
|
+
| Variable | Description |
|
|
44
|
+
|----------|-------------|
|
|
45
|
+
| `DATABASE_URL` | PostgreSQL connection string |
|
|
46
|
+
| `BETTER_AUTH_SECRET` | Secret key for signing tokens |
|
|
47
|
+
| `BETTER_AUTH_URL` | URL of the auth backend |
|
|
48
|
+
| `CORS_ORIGIN` | Allowed frontend origin |
|
|
49
|
+
| `PORT` | Server port (default: 3000) |
|
|
50
|
+
{{#each providers}}
|
|
51
|
+
| `{{uppercase this}}_CLIENT_ID` | {{this}} OAuth client ID |
|
|
52
|
+
| `{{uppercase this}}_CLIENT_SECRET` | {{this}} OAuth client secret |
|
|
53
|
+
{{/each}}
|
|
54
|
+
|
|
55
|
+
## Database
|
|
56
|
+
|
|
57
|
+
This project uses Kysely query builder with PostgreSQL.
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm run db:migrate # Run migrations (creates tables)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Frontend Integration
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { createAuthClient } from "better-auth/react";
|
|
67
|
+
|
|
68
|
+
export const authClient = createAuthClient({
|
|
69
|
+
baseURL: "http://localhost:3000",
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
75
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Kysely, PostgresDialect } from "kysely";
|
|
2
|
+
import pg from "pg";
|
|
3
|
+
import type { Database } from "./types";
|
|
4
|
+
|
|
5
|
+
const dialect = new PostgresDialect({
|
|
6
|
+
pool: new pg.Pool({
|
|
7
|
+
connectionString: process.env.DATABASE_URL,
|
|
8
|
+
}),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export const db = new Kysely<Database>({ dialect });
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Kysely, PostgresDialect, sql } from "kysely";
|
|
2
|
+
import pg from "pg";
|
|
3
|
+
import type { Database } from "./types";
|
|
4
|
+
|
|
5
|
+
async function main() {
|
|
6
|
+
const dialect = new PostgresDialect({
|
|
7
|
+
pool: new pg.Pool({
|
|
8
|
+
connectionString: process.env.DATABASE_URL,
|
|
9
|
+
}),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const db = new Kysely<Database>({ dialect });
|
|
13
|
+
|
|
14
|
+
console.log("Running migrations...");
|
|
15
|
+
|
|
16
|
+
await db.schema
|
|
17
|
+
.createTable("user")
|
|
18
|
+
.ifNotExists()
|
|
19
|
+
.addColumn("id", "text", (col) => col.primaryKey())
|
|
20
|
+
.addColumn("name", "text", (col) => col.notNull())
|
|
21
|
+
.addColumn("email", "text", (col) => col.notNull().unique())
|
|
22
|
+
.addColumn("email_verified", "boolean", (col) => col.notNull().defaultTo(false))
|
|
23
|
+
.addColumn("image", "text")
|
|
24
|
+
.addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))
|
|
25
|
+
.addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))
|
|
26
|
+
.execute();
|
|
27
|
+
|
|
28
|
+
await db.schema
|
|
29
|
+
.createTable("session")
|
|
30
|
+
.ifNotExists()
|
|
31
|
+
.addColumn("id", "text", (col) => col.primaryKey())
|
|
32
|
+
.addColumn("expires_at", "timestamptz", (col) => col.notNull())
|
|
33
|
+
.addColumn("token", "text", (col) => col.notNull().unique())
|
|
34
|
+
.addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))
|
|
35
|
+
.addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))
|
|
36
|
+
.addColumn("ip_address", "text")
|
|
37
|
+
.addColumn("user_agent", "text")
|
|
38
|
+
.addColumn("user_id", "text", (col) => col.notNull().references("user.id"))
|
|
39
|
+
.execute();
|
|
40
|
+
|
|
41
|
+
await db.schema
|
|
42
|
+
.createTable("account")
|
|
43
|
+
.ifNotExists()
|
|
44
|
+
.addColumn("id", "text", (col) => col.primaryKey())
|
|
45
|
+
.addColumn("account_id", "text", (col) => col.notNull())
|
|
46
|
+
.addColumn("provider_id", "text", (col) => col.notNull())
|
|
47
|
+
.addColumn("user_id", "text", (col) => col.notNull().references("user.id"))
|
|
48
|
+
.addColumn("access_token", "text")
|
|
49
|
+
.addColumn("refresh_token", "text")
|
|
50
|
+
.addColumn("id_token", "text")
|
|
51
|
+
.addColumn("access_token_expires_at", "timestamptz")
|
|
52
|
+
.addColumn("refresh_token_expires_at", "timestamptz")
|
|
53
|
+
.addColumn("scope", "text")
|
|
54
|
+
.addColumn("password", "text")
|
|
55
|
+
.addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))
|
|
56
|
+
.addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))
|
|
57
|
+
.execute();
|
|
58
|
+
|
|
59
|
+
await db.schema
|
|
60
|
+
.createTable("verification")
|
|
61
|
+
.ifNotExists()
|
|
62
|
+
.addColumn("id", "text", (col) => col.primaryKey())
|
|
63
|
+
.addColumn("identifier", "text", (col) => col.notNull())
|
|
64
|
+
.addColumn("value", "text", (col) => col.notNull())
|
|
65
|
+
.addColumn("expires_at", "timestamptz", (col) => col.notNull())
|
|
66
|
+
.addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))
|
|
67
|
+
.addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))
|
|
68
|
+
.execute();
|
|
69
|
+
|
|
70
|
+
console.log("Migrations complete.");
|
|
71
|
+
await db.destroy();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
main().catch((err) => {
|
|
75
|
+
console.error("Migration failed:", err);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Generated, ColumnType } from "kysely";
|
|
2
|
+
|
|
3
|
+
export interface Database {
|
|
4
|
+
user: UserTable;
|
|
5
|
+
session: SessionTable;
|
|
6
|
+
account: AccountTable;
|
|
7
|
+
verification: VerificationTable;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface UserTable {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
email: string;
|
|
14
|
+
emailVerified: boolean;
|
|
15
|
+
image: string | null;
|
|
16
|
+
createdAt: Generated<Date>;
|
|
17
|
+
updatedAt: Generated<Date>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface SessionTable {
|
|
21
|
+
id: string;
|
|
22
|
+
expiresAt: Date;
|
|
23
|
+
token: string;
|
|
24
|
+
createdAt: Generated<Date>;
|
|
25
|
+
updatedAt: Generated<Date>;
|
|
26
|
+
ipAddress: string | null;
|
|
27
|
+
userAgent: string | null;
|
|
28
|
+
userId: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface AccountTable {
|
|
32
|
+
id: string;
|
|
33
|
+
accountId: string;
|
|
34
|
+
providerId: string;
|
|
35
|
+
userId: string;
|
|
36
|
+
accessToken: string | null;
|
|
37
|
+
refreshToken: string | null;
|
|
38
|
+
idToken: string | null;
|
|
39
|
+
accessTokenExpiresAt: Date | null;
|
|
40
|
+
refreshTokenExpiresAt: Date | null;
|
|
41
|
+
scope: string | null;
|
|
42
|
+
password: string | null;
|
|
43
|
+
createdAt: Generated<Date>;
|
|
44
|
+
updatedAt: Generated<Date>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface VerificationTable {
|
|
48
|
+
id: string;
|
|
49
|
+
identifier: string;
|
|
50
|
+
value: string;
|
|
51
|
+
expiresAt: Date;
|
|
52
|
+
createdAt: Generated<Date>;
|
|
53
|
+
updatedAt: Generated<Date>;
|
|
54
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{projectName}}",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "tsx watch src/index.ts",
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"start": "node dist/index.js",
|
|
10
|
+
"db:migrate": "tsx db/migrate.ts"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"better-auth": "^1.2.0",
|
|
14
|
+
"hono": "^4.7.0",
|
|
15
|
+
"kysely": "^0.27.0",
|
|
16
|
+
"pg": "^8.13.0"
|
|
17
|
+
{{#if (eq emailProvider "resend")}},
|
|
18
|
+
"resend": "^4.0.0"{{/if}}{{#if (eq emailProvider "sendgrid")}},
|
|
19
|
+
"@sendgrid/mail": "^8.1.0"{{/if}}{{#if (eq emailProvider "smtp")}},
|
|
20
|
+
"nodemailer": "^6.9.0"{{/if}}
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/node": "^22.13.0",
|
|
24
|
+
"@types/pg": "^8.11.0",
|
|
25
|
+
"tsx": "^4.19.0",
|
|
26
|
+
"typescript": "^5.7.0"
|
|
27
|
+
{{#if (eq emailProvider "smtp")}},
|
|
28
|
+
"@types/nodemailer": "^6.4.0"{{/if}}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { betterAuth } from "better-auth";
|
|
2
|
+
import { kyselyAdapter } from "better-auth/adapters/kysely";
|
|
3
|
+
import { db } from "../db/db";
|
|
4
|
+
{{#if twoFactor}}
|
|
5
|
+
import { twoFactor } from "better-auth/plugins";
|
|
6
|
+
{{/if}}
|
|
7
|
+
{{#if rbac}}
|
|
8
|
+
import { admin } from "better-auth/plugins";
|
|
9
|
+
{{/if}}
|
|
10
|
+
{{#if (eq emailProvider "resend")}}
|
|
11
|
+
import { Resend } from "resend";
|
|
12
|
+
|
|
13
|
+
const resend = new Resend(process.env.RESEND_API_KEY);
|
|
14
|
+
{{/if}}
|
|
15
|
+
{{#if (eq emailProvider "sendgrid")}}
|
|
16
|
+
import sgMail from "@sendgrid/mail";
|
|
17
|
+
|
|
18
|
+
sgMail.setApiKey(process.env.SENDGRID_API_KEY!);
|
|
19
|
+
{{/if}}
|
|
20
|
+
{{#if (eq emailProvider "smtp")}}
|
|
21
|
+
import nodemailer from "nodemailer";
|
|
22
|
+
|
|
23
|
+
const transporter = nodemailer.createTransport({
|
|
24
|
+
host: process.env.SMTP_HOST,
|
|
25
|
+
port: Number(process.env.SMTP_PORT) || 587,
|
|
26
|
+
auth: {
|
|
27
|
+
user: process.env.SMTP_USER,
|
|
28
|
+
pass: process.env.SMTP_PASS,
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
{{/if}}
|
|
32
|
+
|
|
33
|
+
export const auth = betterAuth({
|
|
34
|
+
database: kyselyAdapter(db, {
|
|
35
|
+
type: "pg",
|
|
36
|
+
}),
|
|
37
|
+
emailAndPassword: {
|
|
38
|
+
enabled: true,
|
|
39
|
+
{{#if emailProvider}}
|
|
40
|
+
requireEmailVerification: true,
|
|
41
|
+
sendResetPassword: async ({ user, url }) => {
|
|
42
|
+
await sendEmail(user.email, "Reset your password", `<a href="${url}">Reset password</a>`);
|
|
43
|
+
},
|
|
44
|
+
{{/if}}
|
|
45
|
+
},
|
|
46
|
+
session: {
|
|
47
|
+
expiresIn: {{sessionExpiresIn}},
|
|
48
|
+
updateAge: {{sessionUpdateAge}},
|
|
49
|
+
cookieCache: {
|
|
50
|
+
enabled: {{sessionCookieCacheEnabled}},
|
|
51
|
+
maxAge: {{sessionCookieCacheMaxAge}},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
{{#if emailProvider}}
|
|
55
|
+
emailVerification: {
|
|
56
|
+
sendOnSignUp: true,
|
|
57
|
+
sendVerificationEmail: async ({ user, url }) => {
|
|
58
|
+
await sendEmail(user.email, "Verify your email", `<a href="${url}">Verify email</a>`);
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
{{/if}}
|
|
62
|
+
{{#if providers.length}}
|
|
63
|
+
socialProviders: {
|
|
64
|
+
{{#each providers}}
|
|
65
|
+
{{this}}: {
|
|
66
|
+
clientId: process.env.{{uppercase this}}_CLIENT_ID!,
|
|
67
|
+
clientSecret: process.env.{{uppercase this}}_CLIENT_SECRET!,
|
|
68
|
+
},
|
|
69
|
+
{{/each}}
|
|
70
|
+
},
|
|
71
|
+
{{/if}}
|
|
72
|
+
{{#if (or twoFactor rbac)}}
|
|
73
|
+
plugins: [
|
|
74
|
+
{{#if twoFactor}}
|
|
75
|
+
twoFactor(),
|
|
76
|
+
{{/if}}
|
|
77
|
+
{{#if rbac}}
|
|
78
|
+
admin({
|
|
79
|
+
defaultRole: "user",
|
|
80
|
+
}),
|
|
81
|
+
{{/if}}
|
|
82
|
+
],
|
|
83
|
+
{{/if}}
|
|
84
|
+
trustedOrigins: [process.env.CORS_ORIGIN || "http://localhost:3001"],
|
|
85
|
+
});
|
|
86
|
+
{{#if emailProvider}}
|
|
87
|
+
|
|
88
|
+
async function sendEmail(to: string, subject: string, html: string) {
|
|
89
|
+
{{#if (eq emailProvider "resend")}}
|
|
90
|
+
await resend.emails.send({
|
|
91
|
+
from: process.env.EMAIL_FROM || "noreply@example.com",
|
|
92
|
+
to,
|
|
93
|
+
subject,
|
|
94
|
+
html,
|
|
95
|
+
});
|
|
96
|
+
{{/if}}
|
|
97
|
+
{{#if (eq emailProvider "sendgrid")}}
|
|
98
|
+
await sgMail.send({
|
|
99
|
+
from: process.env.EMAIL_FROM || "noreply@example.com",
|
|
100
|
+
to,
|
|
101
|
+
subject,
|
|
102
|
+
html,
|
|
103
|
+
});
|
|
104
|
+
{{/if}}
|
|
105
|
+
{{#if (eq emailProvider "smtp")}}
|
|
106
|
+
await transporter.sendMail({
|
|
107
|
+
from: process.env.EMAIL_FROM || "noreply@example.com",
|
|
108
|
+
to,
|
|
109
|
+
subject,
|
|
110
|
+
html,
|
|
111
|
+
});
|
|
112
|
+
{{/if}}
|
|
113
|
+
}
|
|
114
|
+
{{/if}}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { cors } from "hono/cors";
|
|
3
|
+
import { logger } from "hono/logger";
|
|
4
|
+
import { auth } from "./auth";
|
|
5
|
+
|
|
6
|
+
const app = new Hono();
|
|
7
|
+
|
|
8
|
+
// Middleware
|
|
9
|
+
app.use("*", logger());
|
|
10
|
+
app.use(
|
|
11
|
+
"*",
|
|
12
|
+
cors({
|
|
13
|
+
origin: process.env.CORS_ORIGIN || "http://localhost:3001",
|
|
14
|
+
credentials: true,
|
|
15
|
+
}),
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
// Mount Better Auth handler
|
|
19
|
+
app.on(["POST", "GET"], "/api/auth/**", (c) => {
|
|
20
|
+
return auth.handler(c.req.raw);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Health check
|
|
24
|
+
app.get("/", (c) => {
|
|
25
|
+
return c.json({ status: "ok", message: "Auth backend is running" });
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Start server
|
|
29
|
+
const port = Number(process.env.PORT) || 3000;
|
|
30
|
+
console.log(`Server running on http://localhost:${port}`);
|
|
31
|
+
|
|
32
|
+
export default {
|
|
33
|
+
port,
|
|
34
|
+
fetch: app.fetch,
|
|
35
|
+
};
|