Skip to content

Commit 0dd320d

Browse files
feat: 🎸 Init Commit
0 parents  commit 0dd320d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+11930
-0
lines changed

.env.example

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
NEXT_PUBLIC_BASE_URL="http://localhost:3000"
2+
DATABASE_URL="postgresql://postgres:Letmein!@localhost:5432/db"
3+
4+
# openssl rand -base64 24;
5+
JWT_SECRET="secret"
6+
7+
# Email Provider
8+
EMAIL_SERVER_USER=admin
9+
EMAIL_SERVER_PASSWORD=password
10+
EMAIL_SERVER_HOST=localhost
11+
EMAIL_SERVER_PORT=1025
12+
EMAIL_SERVER_SECURE=false
13+
EMAIL_FROM=noreply@localhost

.eslintrc.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "next/core-web-vitals"
3+
}

.gitignore

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
.yarn/install-state.gz
8+
9+
# testing
10+
/coverage
11+
12+
# next.js
13+
/.next/
14+
/out/
15+
16+
# production
17+
/build
18+
19+
# misc
20+
.DS_Store
21+
*.pem
22+
23+
# debug
24+
npm-debug.log*
25+
yarn-debug.log*
26+
yarn-error.log*
27+
28+
# local env files
29+
.env
30+
.env*.local
31+
32+
# vercel
33+
.vercel
34+
35+
# typescript
36+
*.tsbuildinfo
37+
next-env.d.ts

.nvmrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
20.14.0

README.md

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# NextJS Lucia Passwordless / Magiclink Postres Docker
2+
3+
The following is an example implementing Lucia magilink authentication with postgres.
4+
5+
## Requirements
6+
7+
- Node `v20` or greater
8+
- Pnpm
9+
- Docker
10+
11+
## Quick Setup
12+
13+
### 1 - Install Dependencies
14+
15+
```bash
16+
# FROM: ./
17+
18+
pnpm install;
19+
```
20+
21+
### 2 - Set Environment Variables
22+
23+
```bash
24+
# FROM: ./
25+
26+
cp .env.example .env;
27+
```
28+
29+
### 3 - Start Database
30+
31+
```bash
32+
# FROM: ./
33+
34+
pnpm db:up;
35+
```
36+
37+
### 4 - Generate Local Database
38+
39+
```bash
40+
# FROM: ./
41+
42+
pnpm db:gen;
43+
```
44+
45+
### 5 - Push Database Changes
46+
47+
```bash
48+
# FROM: ./
49+
50+
pnpm db:push;
51+
```
52+
53+
### 6 - Run App
54+
55+
```bash
56+
# FROM: ./
57+
58+
pnpm dev;
59+
60+
# [Expected Output]:
61+
# ▲ Next.js 14.2.3
62+
# - Local: http://localhost:3000
63+
# - Environments: .env.local
64+
#
65+
# ✓ Starting...
66+
# ✓ Ready in 1785ms
67+
```
68+
69+
### 7 - Run Drizzle Studio
70+
71+
```bash
72+
# FROM: ./
73+
74+
pnpm db:studio;
75+
76+
# [Expected Output]:
77+
# ...
78+
# Drizzle Studio is up and running on https://local.drizzle.studio
79+
```
80+
81+
### 8 - See Mailhog Email Server
82+
83+
```bash
84+
# FROM: ./
85+
86+
open http://localhost:8025
87+
```
88+
89+
### 9 - Destroy Database
90+
91+
```bash
92+
# FROM: ./
93+
94+
pnpm db:down;
95+
```

components.json

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"$schema": "https://ui.shadcn.com/schema.json",
3+
"style": "default",
4+
"rsc": true,
5+
"tsx": true,
6+
"tailwind": {
7+
"config": "tailwind.config.ts",
8+
"css": "src/app/globals.css",
9+
"baseColor": "slate",
10+
"cssVariables": true,
11+
"prefix": ""
12+
},
13+
"aliases": {
14+
"components": "@/components",
15+
"utils": "@/lib/utils"
16+
}
17+
}

docker-compose.yml

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
version: '3.9'
2+
services:
3+
db:
4+
image: postgres:16-alpine
5+
restart: always
6+
environment:
7+
POSTGRES_USER: postgres
8+
POSTGRES_PASSWORD: Letmein!
9+
ports:
10+
- '5432:5432'
11+
volumes:
12+
- ./docker_postgres_init.sql:/docker-entrypoint-initdb.d/docker_postgres_init.sql
13+
expose:
14+
- '5432'
15+
email:
16+
image: mailhog/mailhog:latest
17+
restart: always
18+
ports:
19+
- "1025:1025"
20+
- "8025:8025"

docker_postgres_init.sql

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CREATE DATABASE db
2+
WITH
3+
OWNER = postgres
4+
ENCODING = 'UTF8'
5+
LC_COLLATE = 'en_US.utf8'
6+
LC_CTYPE = 'en_US.utf8'
7+
TABLESPACE = pg_default
8+
CONNECTION LIMIT = -1;

drizzle.config.ts

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Imports
2+
// =================================
3+
import { defineConfig } from "drizzle-kit";
4+
import { env } from "@/env";
5+
6+
// Main Drizzle Config
7+
// =================================
8+
export default defineConfig({
9+
schema: "src/lib/db/schema.ts",
10+
dialect: "postgresql",
11+
dbCredentials: {
12+
url: env.DATABASE_URL,
13+
},
14+
});

drizzle/0000_mute_stranger.sql

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
CREATE TABLE IF NOT EXISTS "magic_link" (
2+
"id" text PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3+
"user_id" text NOT NULL,
4+
"code" text NOT NULL
5+
);
6+
--> statement-breakpoint
7+
CREATE TABLE IF NOT EXISTS "session" (
8+
"id" text PRIMARY KEY NOT NULL,
9+
"user_id" text NOT NULL,
10+
"expires_at" timestamp with time zone NOT NULL
11+
);
12+
--> statement-breakpoint
13+
CREATE TABLE IF NOT EXISTS "user" (
14+
"id" text PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
15+
"name" text NOT NULL,
16+
"email" text NOT NULL,
17+
CONSTRAINT "user_email_unique" UNIQUE("email")
18+
);
19+
--> statement-breakpoint
20+
DO $$ BEGIN
21+
ALTER TABLE "magic_link" ADD CONSTRAINT "magic_link_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;
22+
EXCEPTION
23+
WHEN duplicate_object THEN null;
24+
END $$;
25+
--> statement-breakpoint
26+
DO $$ BEGIN
27+
ALTER TABLE "session" ADD CONSTRAINT "session_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;
28+
EXCEPTION
29+
WHEN duplicate_object THEN null;
30+
END $$;

drizzle/meta/0000_snapshot.json

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
{
2+
"id": "47a75852-c834-4b30-8106-42ee3111a8d5",
3+
"prevId": "00000000-0000-0000-0000-000000000000",
4+
"version": "7",
5+
"dialect": "postgresql",
6+
"tables": {
7+
"public.magic_link": {
8+
"name": "magic_link",
9+
"schema": "",
10+
"columns": {
11+
"id": {
12+
"name": "id",
13+
"type": "text",
14+
"primaryKey": true,
15+
"notNull": true,
16+
"default": "gen_random_uuid()"
17+
},
18+
"user_id": {
19+
"name": "user_id",
20+
"type": "text",
21+
"primaryKey": false,
22+
"notNull": true
23+
},
24+
"code": {
25+
"name": "code",
26+
"type": "text",
27+
"primaryKey": false,
28+
"notNull": true
29+
}
30+
},
31+
"indexes": {},
32+
"foreignKeys": {
33+
"magic_link_user_id_user_id_fk": {
34+
"name": "magic_link_user_id_user_id_fk",
35+
"tableFrom": "magic_link",
36+
"tableTo": "user",
37+
"columnsFrom": [
38+
"user_id"
39+
],
40+
"columnsTo": [
41+
"id"
42+
],
43+
"onDelete": "no action",
44+
"onUpdate": "no action"
45+
}
46+
},
47+
"compositePrimaryKeys": {},
48+
"uniqueConstraints": {}
49+
},
50+
"public.session": {
51+
"name": "session",
52+
"schema": "",
53+
"columns": {
54+
"id": {
55+
"name": "id",
56+
"type": "text",
57+
"primaryKey": true,
58+
"notNull": true
59+
},
60+
"user_id": {
61+
"name": "user_id",
62+
"type": "text",
63+
"primaryKey": false,
64+
"notNull": true
65+
},
66+
"expires_at": {
67+
"name": "expires_at",
68+
"type": "timestamp with time zone",
69+
"primaryKey": false,
70+
"notNull": true
71+
}
72+
},
73+
"indexes": {},
74+
"foreignKeys": {
75+
"session_user_id_user_id_fk": {
76+
"name": "session_user_id_user_id_fk",
77+
"tableFrom": "session",
78+
"tableTo": "user",
79+
"columnsFrom": [
80+
"user_id"
81+
],
82+
"columnsTo": [
83+
"id"
84+
],
85+
"onDelete": "no action",
86+
"onUpdate": "no action"
87+
}
88+
},
89+
"compositePrimaryKeys": {},
90+
"uniqueConstraints": {}
91+
},
92+
"public.user": {
93+
"name": "user",
94+
"schema": "",
95+
"columns": {
96+
"id": {
97+
"name": "id",
98+
"type": "text",
99+
"primaryKey": true,
100+
"notNull": true,
101+
"default": "gen_random_uuid()"
102+
},
103+
"name": {
104+
"name": "name",
105+
"type": "text",
106+
"primaryKey": false,
107+
"notNull": true
108+
},
109+
"email": {
110+
"name": "email",
111+
"type": "text",
112+
"primaryKey": false,
113+
"notNull": true
114+
}
115+
},
116+
"indexes": {},
117+
"foreignKeys": {},
118+
"compositePrimaryKeys": {},
119+
"uniqueConstraints": {
120+
"user_email_unique": {
121+
"name": "user_email_unique",
122+
"nullsNotDistinct": false,
123+
"columns": [
124+
"email"
125+
]
126+
}
127+
}
128+
}
129+
},
130+
"enums": {},
131+
"schemas": {},
132+
"_meta": {
133+
"columns": {},
134+
"schemas": {},
135+
"tables": {}
136+
}
137+
}

0 commit comments

Comments
 (0)