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,35 @@
|
|
|
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:generate": "drizzle-kit generate",
|
|
11
|
+
"db:migrate": "tsx drizzle/migrate.ts",
|
|
12
|
+
"db:push": "drizzle-kit push",
|
|
13
|
+
"db:studio": "drizzle-kit studio"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@fastify/cors": "^10.0.0",
|
|
17
|
+
"better-auth": "^1.2.0",
|
|
18
|
+
"drizzle-orm": "^0.38.0",
|
|
19
|
+
"fastify": "^5.2.0",
|
|
20
|
+
"pg": "^8.13.0"
|
|
21
|
+
{{#if (eq emailProvider "resend")}},
|
|
22
|
+
"resend": "^4.0.0"{{/if}}{{#if (eq emailProvider "sendgrid")}},
|
|
23
|
+
"@sendgrid/mail": "^8.1.0"{{/if}}{{#if (eq emailProvider "smtp")}},
|
|
24
|
+
"nodemailer": "^6.9.0"{{/if}}
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^22.13.0",
|
|
28
|
+
"@types/pg": "^8.11.0",
|
|
29
|
+
"drizzle-kit": "^0.30.0",
|
|
30
|
+
"tsx": "^4.19.0",
|
|
31
|
+
"typescript": "^5.7.0"
|
|
32
|
+
{{#if (eq emailProvider "smtp")}},
|
|
33
|
+
"@types/nodemailer": "^6.4.0"{{/if}}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { betterAuth } from "better-auth";
|
|
2
|
+
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
|
3
|
+
import { db } from "../drizzle/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: drizzleAdapter(db, {
|
|
35
|
+
provider: "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,34 @@
|
|
|
1
|
+
import Fastify from "fastify";
|
|
2
|
+
import cors from "@fastify/cors";
|
|
3
|
+
import { auth } from "./auth";
|
|
4
|
+
import { toNodeHandler } from "better-auth/node";
|
|
5
|
+
|
|
6
|
+
const app = Fastify({ logger: true });
|
|
7
|
+
|
|
8
|
+
// CORS
|
|
9
|
+
await app.register(cors, {
|
|
10
|
+
origin: process.env.CORS_ORIGIN || "http://localhost:3001",
|
|
11
|
+
credentials: true,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
// Mount Better Auth handler
|
|
15
|
+
app.all("/api/auth/*", async (req, reply) => {
|
|
16
|
+
const handler = toNodeHandler(auth);
|
|
17
|
+
// @ts-ignore - bridge Fastify to Node handler
|
|
18
|
+
handler(req.raw, reply.raw);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Health check
|
|
22
|
+
app.get("/", async () => {
|
|
23
|
+
return { status: "ok", message: "Auth backend is running" };
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Start server
|
|
27
|
+
const port = Number(process.env.PORT) || 3000;
|
|
28
|
+
try {
|
|
29
|
+
await app.listen({ port, host: "0.0.0.0" });
|
|
30
|
+
console.log(`Server running on http://localhost:${port}`);
|
|
31
|
+
} catch (err) {
|
|
32
|
+
app.log.error(err);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
@@ -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=sqlite.db
|
|
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,78 @@
|
|
|
1
|
+
# {{projectName}}
|
|
2
|
+
|
|
3
|
+
Authentication backend powered by [Better Auth](https://better-auth.com), built with Fastify + Drizzle + 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
|
+
# Push database schema
|
|
19
|
+
npm run db:push
|
|
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 Drizzle ORM with PostgreSQL.
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm run db:generate # Generate migrations
|
|
61
|
+
npm run db:migrate # Run migrations
|
|
62
|
+
npm run db:push # Push schema changes directly
|
|
63
|
+
npm run db:studio # Open Drizzle Studio
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Frontend Integration
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { createAuthClient } from "better-auth/react";
|
|
70
|
+
|
|
71
|
+
export const authClient = createAuthClient({
|
|
72
|
+
baseURL: "http://localhost:3000",
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## License
|
|
77
|
+
|
|
78
|
+
MIT
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { drizzle } from "drizzle-orm/better-sqlite3";
|
|
2
|
+
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
|
|
3
|
+
import Database from "better-sqlite3";
|
|
4
|
+
|
|
5
|
+
const sqlite = new Database(process.env.DATABASE_URL || "sqlite.db");
|
|
6
|
+
const db = drizzle(sqlite);
|
|
7
|
+
|
|
8
|
+
console.log("Running migrations...");
|
|
9
|
+
migrate(db, { migrationsFolder: "./drizzle/migrations" });
|
|
10
|
+
console.log("Migrations complete.");
|
|
11
|
+
|
|
12
|
+
sqlite.close();
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {
|
|
2
|
+
sqliteTable,
|
|
3
|
+
text,
|
|
4
|
+
integer,
|
|
5
|
+
} from "drizzle-orm/sqlite-core";
|
|
6
|
+
|
|
7
|
+
export const user = sqliteTable("user", {
|
|
8
|
+
id: text("id").primaryKey(),
|
|
9
|
+
name: text("name").notNull(),
|
|
10
|
+
email: text("email").notNull().unique(),
|
|
11
|
+
emailVerified: integer("email_verified", { mode: "boolean" }).notNull().default(false),
|
|
12
|
+
image: text("image"),
|
|
13
|
+
createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
|
|
14
|
+
updatedAt: integer("updated_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export const session = sqliteTable("session", {
|
|
18
|
+
id: text("id").primaryKey(),
|
|
19
|
+
expiresAt: integer("expires_at", { mode: "timestamp" }).notNull(),
|
|
20
|
+
token: text("token").notNull().unique(),
|
|
21
|
+
createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
|
|
22
|
+
updatedAt: integer("updated_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
|
|
23
|
+
ipAddress: text("ip_address"),
|
|
24
|
+
userAgent: text("user_agent"),
|
|
25
|
+
userId: text("user_id")
|
|
26
|
+
.notNull()
|
|
27
|
+
.references(() => user.id, { onDelete: "cascade" }),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export const account = sqliteTable("account", {
|
|
31
|
+
id: text("id").primaryKey(),
|
|
32
|
+
accountId: text("account_id").notNull(),
|
|
33
|
+
providerId: text("provider_id").notNull(),
|
|
34
|
+
userId: text("user_id")
|
|
35
|
+
.notNull()
|
|
36
|
+
.references(() => user.id, { onDelete: "cascade" }),
|
|
37
|
+
accessToken: text("access_token"),
|
|
38
|
+
refreshToken: text("refresh_token"),
|
|
39
|
+
idToken: text("id_token"),
|
|
40
|
+
accessTokenExpiresAt: integer("access_token_expires_at", { mode: "timestamp" }),
|
|
41
|
+
refreshTokenExpiresAt: integer("refresh_token_expires_at", { mode: "timestamp" }),
|
|
42
|
+
scope: text("scope"),
|
|
43
|
+
password: text("password"),
|
|
44
|
+
createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
|
|
45
|
+
updatedAt: integer("updated_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
export const verification = sqliteTable("verification", {
|
|
49
|
+
id: text("id").primaryKey(),
|
|
50
|
+
identifier: text("identifier").notNull(),
|
|
51
|
+
value: text("value").notNull(),
|
|
52
|
+
expiresAt: integer("expires_at", { mode: "timestamp" }).notNull(),
|
|
53
|
+
createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
|
|
54
|
+
updatedAt: integer("updated_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
|
|
55
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
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:generate": "drizzle-kit generate",
|
|
11
|
+
"db:migrate": "tsx drizzle/migrate.ts",
|
|
12
|
+
"db:push": "drizzle-kit push",
|
|
13
|
+
"db:studio": "drizzle-kit studio"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@fastify/cors": "^10.0.0",
|
|
17
|
+
"better-auth": "^1.2.0",
|
|
18
|
+
"better-sqlite3": "^11.7.0",
|
|
19
|
+
"drizzle-orm": "^0.38.0",
|
|
20
|
+
"fastify": "^5.2.0"
|
|
21
|
+
{{#if (eq emailProvider "resend")}},
|
|
22
|
+
"resend": "^4.0.0"{{/if}}{{#if (eq emailProvider "sendgrid")}},
|
|
23
|
+
"@sendgrid/mail": "^8.1.0"{{/if}}{{#if (eq emailProvider "smtp")}},
|
|
24
|
+
"nodemailer": "^6.9.0"{{/if}}
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/better-sqlite3": "^7.6.0",
|
|
28
|
+
"@types/node": "^22.13.0",
|
|
29
|
+
"drizzle-kit": "^0.30.0",
|
|
30
|
+
"tsx": "^4.19.0",
|
|
31
|
+
"typescript": "^5.7.0"
|
|
32
|
+
{{#if (eq emailProvider "smtp")}},
|
|
33
|
+
"@types/nodemailer": "^6.4.0"{{/if}}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { betterAuth } from "better-auth";
|
|
2
|
+
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
|
3
|
+
import { db } from "../drizzle/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: drizzleAdapter(db, {
|
|
35
|
+
provider: "sqlite",
|
|
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,34 @@
|
|
|
1
|
+
import Fastify from "fastify";
|
|
2
|
+
import cors from "@fastify/cors";
|
|
3
|
+
import { auth } from "./auth";
|
|
4
|
+
import { toNodeHandler } from "better-auth/node";
|
|
5
|
+
|
|
6
|
+
const app = Fastify({ logger: true });
|
|
7
|
+
|
|
8
|
+
// CORS
|
|
9
|
+
await app.register(cors, {
|
|
10
|
+
origin: process.env.CORS_ORIGIN || "http://localhost:3001",
|
|
11
|
+
credentials: true,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
// Mount Better Auth handler
|
|
15
|
+
app.all("/api/auth/*", async (req, reply) => {
|
|
16
|
+
const handler = toNodeHandler(auth);
|
|
17
|
+
// @ts-ignore - bridge Fastify to Node handler
|
|
18
|
+
handler(req.raw, reply.raw);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Health check
|
|
22
|
+
app.get("/", async () => {
|
|
23
|
+
return { status: "ok", message: "Auth backend is running" };
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Start server
|
|
27
|
+
const port = Number(process.env.PORT) || 3000;
|
|
28
|
+
try {
|
|
29
|
+
await app.listen({ port, host: "0.0.0.0" });
|
|
30
|
+
console.log(`Server running on http://localhost:${port}`);
|
|
31
|
+
} catch (err) {
|
|
32
|
+
app.log.error(err);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
@@ -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=mysql://user:password@localhost:3306/{{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}}
|