Skip to content

Commit 4ecfa44

Browse files
authored
Merge pull request #49 from GBSL-Informatik/refactor/better-auth
Refactor/better auth
2 parents acef9f5 + ddfd15f commit 4ecfa44

Some content is hidden

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

51 files changed

+3770
-3611
lines changed

.eslintrc.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"env": {
3+
"es2021": true,
4+
"node": true
5+
},
6+
"extends": ["prettier"],
7+
"plugins": ["prettier", "@typescript-eslint"],
8+
"parserOptions": {
9+
"ecmaVersion": "latest",
10+
"sourceType": "module"
11+
},
12+
"rules": {
13+
"prettier/prettier": [
14+
"error",
15+
{
16+
"arrowParens": "always",
17+
"bracketSpacing": true,
18+
"bracketSameLine": false,
19+
"printWidth": 110,
20+
"proseWrap": "never",
21+
"singleQuote": true,
22+
"trailingComma": "none",
23+
"tabWidth": 4
24+
}
25+
]
26+
},
27+
"parser": "@typescript-eslint/parser"
28+
}

.github/workflows/prettier-check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
- name: Set up Node.js
1818
uses: actions/setup-node@v4
1919
with:
20-
node-version: '>=22.11'
20+
node-version: '>=22.15'
2121

2222
- name: Install dependencies
2323
run: yarn install

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ node_modules
44
docs/prisma/**/*
55
docs/*.svg
66
dist/
7+
build/
78
# Sentry Config File
89
.sentryclirc
9-
10+
*.dump
1011
src/generated/prisma

.prettierrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77
"singleQuote": true,
88
"trailingComma": "none",
99
"tabWidth": 4
10-
}
10+
}

README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -296,16 +296,17 @@ dokku letsencrypt:enable dev-teaching-api
296296
## when it succeeds, re-enable the cloudflare proxy for domain.tld...
297297
```
298298

299-
### Speed Improvements
300-
If the API and the Database are running on the same server, you can improve the speed by disabling the tcp connection for the database. This can be done by setting the `DATABASE_URL` to `postgresql://teaching_website:teaching_website@localhost/teaching_website?sslmode=disable`.
301-
302-
## Troubleshooting
299+
## Dump from production
303300

304-
> [!Caution]
305-
> Authentication Error: When your API can not authenticate requests
306-
> - set the debug level in authConfig to 'info' and check the logs
307-
> - when it is a 401 error and the issue is about `Strategy.prototype.jwtVerify can not verify the token`, ensure to set `"requestedAccessTokenVersion": 2` in the API manifest (!! **not** in the Frontend's manifest, there it must still be `null` !!)
301+
```bash
302+
# inside shell of VSCode DevContainer (with configured dokku git remote)
303+
dokku postgres:export dev-teaching-api > tdev-backup.dump
304+
pg_restore -h localhost --verbose --clean --no-owner --no-privileges -U postgres -d teaching_api < tdev-backup.dump
305+
# when ai-pr was once merged/deployed to the db, run `delete from _prisma_migrations where migration_name ilike '%_ai_%';`
306+
```
308307

308+
## Speed Improvements
309+
If the API and the Database are running on the same server, you can improve the speed by disabling the tcp connection for the database. This can be done by setting the `DATABASE_URL` to `postgresql://teaching_website:teaching_website@localhost/teaching_website?sslmode=disable`.
309310

310311
## CMS
311312

eslint.config.mjs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { defineConfig } from 'eslint/config';
2+
import prettier from 'eslint-plugin-prettier';
3+
import typescriptEslint from '@typescript-eslint/eslint-plugin';
4+
import globals from 'globals';
5+
import tsParser from '@typescript-eslint/parser';
6+
import path from 'node:path';
7+
import { fileURLToPath } from 'node:url';
8+
import js from '@eslint/js';
9+
import { FlatCompat } from '@eslint/eslintrc';
10+
11+
const __filename = fileURLToPath(import.meta.url);
12+
const __dirname = path.dirname(__filename);
13+
const compat = new FlatCompat({
14+
baseDirectory: __dirname,
15+
recommendedConfig: js.configs.recommended,
16+
allConfig: js.configs.all
17+
});
18+
19+
export default defineConfig([
20+
{
21+
extends: compat.extends('prettier'),
22+
23+
plugins: {
24+
prettier,
25+
'@typescript-eslint': typescriptEslint
26+
},
27+
28+
languageOptions: {
29+
globals: {
30+
...globals.node
31+
},
32+
33+
parser: tsParser,
34+
ecmaVersion: 'latest',
35+
sourceType: 'module'
36+
},
37+
38+
rules: {
39+
'prettier/prettier': [
40+
'error',
41+
{
42+
arrowParens: 'always',
43+
bracketSpacing: true,
44+
bracketSameLine: false,
45+
printWidth: 110,
46+
proseWrap: 'never',
47+
singleQuote: true,
48+
trailingComma: 'none',
49+
tabWidth: 4
50+
}
51+
]
52+
}
53+
}
54+
]);

package.json

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,66 @@
11
{
22
"name": "teaching-website-backend",
33
"version": "1.0.0",
4-
"main": "index.js",
4+
"main": "server.js",
55
"repository": "https://github.com/GBSL-Informatik/teaching-website-backend.git",
66
"author": "GBSL Informatik",
7-
"license": "CC-BY-SA",
7+
"license": "MIT",
88
"scripts": {
9-
"build": "yarn run prisma generate && tsc --build ./tsconfig.build.json && (yarn sentry:sourcemaps || true)",
10-
"start": "node -r dotenv/config ./dist/src/server.js",
11-
"dev": "dotenv -- nodemon src/server.ts",
12-
"dummy:run": "ts-node -r dotenv/config ./bin/dummy.ts",
9+
"dev": "cross-env NODE_ENV=development nodemon -r tsconfig-paths/register --exec ts-node ./src/server.ts --files",
10+
"build": "yarn run prisma generate && tsc --build ./tsconfig.build.json",
11+
"start": "cross-env NODE_ENV=production node ./dist/src/server.js",
12+
"lint": "eslint . --ignore-pattern node_modules --fix",
13+
"format": "prettier --write ./**/*.{ts,json}",
14+
"format:check": "prettier --check ./**/*.{ts,json}",
1315
"db:migrate": "yarn prisma migrate deploy",
1416
"db:migrate:dev": "yarn prisma migrate dev",
1517
"db:seed": "yarn prisma db seed",
1618
"db:reset": "dotenv -- ts-node prisma/reset.ts",
1719
"db:recreate": "yarn run db:reset && yarn run db:migrate && yarn run db:seed",
18-
"format": "prettier --write .",
19-
"format:check": "prettier --check .",
2020
"sentry:sourcemaps": "sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_PROJECT ./dist && sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_PROJECT ./dist"
2121
},
2222
"dependencies": {
23-
"@prisma/adapter-pg": "^6.15.0",
24-
"@prisma/client": "^6.15.0",
23+
"@better-auth/sso": "^1.3.26",
24+
"@prisma/adapter-pg": "^6.16.2",
25+
"@prisma/client": "^6.16.2",
2526
"@sentry/cli": "^2.52.0",
2627
"@sentry/node": "^10.8.0",
27-
"connect-pg-simple": "^9.0.1",
28+
"better-auth": "^1.3.27",
2829
"cors": "^2.8.5",
30+
"cross-env": "^10.0.0",
31+
"dotenv": "^17.2.2",
2932
"es-toolkit": "^1.39.10",
30-
"express": "^4.19.2",
31-
"express-session": "^1.18.0",
33+
"express": "^5.1.0",
3234
"global": "^4.4.0",
3335
"morgan": "^1.10.0",
34-
"passport": "^0.7.0",
35-
"passport-azure-ad": "^4.3.5",
3636
"socket.io": "^4.8.1",
3737
"winston": "^3.13.0"
3838
},
39-
"prisma": {
40-
"schema": "./prisma/schema.prisma",
41-
"seed": "dotenv -- ts-node prisma/seed.ts",
42-
"reset": "dotenv -- ts-node prisma/reset.ts"
43-
},
4439
"devDependencies": {
4540
"@mermaid-js/mermaid-cli": "^10.9.1",
46-
"@types/connect-pg-simple": "^7.0.3",
4741
"@types/cors": "^2.8.17",
48-
"@types/express": "^4.17.21",
42+
"@types/express": "^5.0.3",
4943
"@types/morgan": "^1.9.9",
5044
"@types/node": "^20.14.6",
51-
"@types/passport-azure-ad": "^4.3.6",
45+
"@typescript-eslint/eslint-plugin": "^8.44.1",
46+
"@typescript-eslint/parser": "^8.44.1",
5247
"dotenv-cli": "^7.4.2",
53-
"nodemon": "^3.1.3",
54-
"prettier": "^3.3.2",
55-
"prisma": "^6.15.0",
48+
"eslint": "^9.36.0",
49+
"eslint-config-prettier": "^10.1.8",
50+
"eslint-plugin-prettier": "^5.5.4",
51+
"nodemon": "^3.1.10",
52+
"prettier": "^3.6.2",
53+
"prisma": "^6.17.1",
5654
"prisma-dbml-generator": "^0.12.0",
5755
"prisma-docs-generator": "^0.8.0",
58-
"prisma-erd-generator": "^2.0.4",
56+
"prisma-erd-generator": "^2.1.0",
5957
"ts-node": "^10.9.2",
60-
"typescript": "^5.5.4"
58+
"tsc-alias": "^1.8.16",
59+
"tsconfig-paths": "^4.2.0",
60+
"typescript": "^5.9.2",
61+
"typescript-transform-paths": "^3.5.5"
6162
},
6263
"engines": {
63-
"node": "^22.11.0"
64+
"node": "^22.15.0"
6465
}
65-
}
66+
}

prisma.config.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import 'dotenv/config';
2+
import path from 'node:path';
3+
4+
import type { PrismaConfig } from 'prisma';
5+
6+
export default {
7+
experimental: {
8+
adapter: true
9+
},
10+
migrations: {
11+
seed: 'dotenv -- ts-node prisma/seed.ts'
12+
}
13+
// now you can use process.env variables
14+
} satisfies PrismaConfig;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*
2+
Warnings:
3+
4+
- You are about to drop the `sessions` table. If the table is not empty, all the data it contains will be lost.
5+
6+
*/
7+
-- DropTable
8+
DROP TABLE "public"."sessions";
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
Warnings:
3+
4+
- The `role` column on the `users` table would be dropped and recreated. This will lead to data loss if there is data in the column.
5+
6+
*/
7+
-- AlterTable
8+
ALTER TABLE "public"."users"
9+
ADD COLUMN "ban_expires" TIMESTAMP(3),
10+
ADD COLUMN "ban_reason" TEXT,
11+
ADD COLUMN "banned" BOOLEAN DEFAULT false,
12+
ADD COLUMN "email_verified" BOOLEAN NOT NULL DEFAULT false,
13+
ADD COLUMN "image" TEXT,
14+
ADD COLUMN "name" TEXT NOT NULL DEFAULT '',
15+
ADD COLUMN "trole" TEXT NOT NULL DEFAULT 'student';
16+
17+
UPDATE "public"."users" SET "trole" = 'admin' WHERE "role" = 'ADMIN';
18+
UPDATE "public"."users" SET "trole" = 'teacher' WHERE "role" = 'TEACHER';
19+
20+
ALTER TABLE "public"."users"
21+
DROP COLUMN "role";
22+
23+
ALTER TABLE "public"."users"
24+
ADD COLUMN "role" TEXT NOT NULL DEFAULT 'student';
25+
26+
UPDATE "public"."users" SET "role" = trole;
27+
UPDATE "public"."users" SET "name" = CONCAT(first_name, ' ', last_name) WHERE name = '';
28+
29+
ALTER TABLE "public"."users"
30+
DROP COLUMN "trole";
31+
32+
-- DropEnum
33+
DROP TYPE "public"."Role";
34+
35+
-- CreateTable
36+
CREATE TABLE "public"."sessions" (
37+
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
38+
"ip_address" TEXT,
39+
"user_agent" TEXT,
40+
"user_id" UUID NOT NULL,
41+
"token" TEXT NOT NULL,
42+
"expires_at" TIMESTAMP(3) NOT NULL,
43+
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
44+
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
45+
"impersonated_by" UUID,
46+
47+
CONSTRAINT "sessions_pkey" PRIMARY KEY ("id")
48+
);
49+
50+
-- CreateTable
51+
CREATE TABLE "public"."accounts" (
52+
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
53+
"account_id" TEXT NOT NULL,
54+
"provider_id" TEXT NOT NULL,
55+
"user_id" UUID NOT NULL,
56+
"access_token" TEXT,
57+
"refresh_token" TEXT,
58+
"id_token" TEXT,
59+
"expires_at" TIMESTAMP(3),
60+
"password" TEXT,
61+
"access_token_expires_at" TIMESTAMP(3),
62+
"refresh_token_expires_at" TIMESTAMP(3),
63+
"scope" TEXT,
64+
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
65+
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
66+
67+
CONSTRAINT "accounts_pkey" PRIMARY KEY ("id")
68+
);
69+
70+
-- CreateTable
71+
CREATE TABLE "public"."verifications" (
72+
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
73+
"identifier" TEXT NOT NULL,
74+
"value" TEXT NOT NULL,
75+
"expires_at" TIMESTAMP(3) NOT NULL,
76+
"created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,
77+
"updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,
78+
79+
CONSTRAINT "verifications_pkey" PRIMARY KEY ("id")
80+
);
81+
82+
-- CreateIndex
83+
CREATE UNIQUE INDEX "sessions_token_key" ON "public"."sessions"("token");
84+
85+
-- CreateIndex
86+
CREATE INDEX "sessions_user_id_idx" ON "public"."sessions"("user_id");
87+
88+
-- CreateIndex
89+
CREATE INDEX "sessions_user_id_token_idx" ON "public"."sessions"("user_id", "token");
90+
91+
-- CreateIndex
92+
CREATE INDEX "accounts_user_id_idx" ON "public"."accounts"("user_id");
93+
94+
-- CreateIndex
95+
CREATE INDEX "verifications_identifier_idx" ON "public"."verifications"("identifier");
96+
97+
-- AddForeignKey
98+
ALTER TABLE "public"."sessions" ADD CONSTRAINT "sessions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
99+
100+
-- AddForeignKey
101+
ALTER TABLE "public"."accounts" ADD CONSTRAINT "accounts_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE CASCADE ON UPDATE CASCADE;

0 commit comments

Comments
 (0)