Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
83be49c
add dependency
lebalz Sep 24, 2025
895150b
remove legacy try-catch route handlers
lebalz Sep 24, 2025
ab1d2d2
update types
lebalz Sep 25, 2025
47fff51
update error handling and comment out login-strategy
lebalz Sep 25, 2025
339dbee
try ts confgi
lebalz Sep 25, 2025
f010b65
make it running
lebalz Sep 26, 2025
c031755
add eslintconfig
lebalz Sep 26, 2025
973f05a
update
lebalz Sep 26, 2025
13eae8b
update ts
lebalz Sep 26, 2025
c7a7466
remove passport, use any as user
lebalz Sep 26, 2025
ee31270
fix prisma schema
lebalz Sep 27, 2025
7412f5d
fix seed
lebalz Sep 27, 2025
759293a
update prisma
lebalz Sep 27, 2025
cbc4a2e
config
lebalz Sep 27, 2025
ba78e4f
add migration
lebalz Sep 28, 2025
5b2e13a
rename user.role to user.tdev_role
lebalz Sep 28, 2025
464a2c6
add admin-plugin
lebalz Sep 28, 2025
556278a
add sso plugin
lebalz Sep 28, 2025
e059d53
add sso plugin
lebalz Sep 28, 2025
6ca021d
some implementations
lebalz Sep 28, 2025
f17ef79
poc of better-auth
lebalz Oct 6, 2025
f52b454
add readme section about dumping db
lebalz Oct 6, 2025
5178482
fix migrations
lebalz Oct 6, 2025
3efff15
fix build command
lebalz Oct 6, 2025
68f07f7
update dependencies
lebalz Oct 6, 2025
be09f6d
fix imports
lebalz Oct 6, 2025
e3646b3
pin node version
lebalz Oct 6, 2025
4ae14aa
pin v22.20
lebalz Oct 6, 2025
c92b0dd
15.1
lebalz Oct 6, 2025
9113297
24
lebalz Oct 6, 2025
fd47e9b
24.x
lebalz Oct 6, 2025
82c57cf
heroku
lebalz Oct 6, 2025
f1d3383
22.15.0
lebalz Oct 7, 2025
0cd66be
^22.15.0
lebalz Oct 7, 2025
7bc9bc6
fix to
lebalz Oct 7, 2025
cc672d8
tmp fix origin
lebalz Oct 9, 2025
4a6daac
add oAuthProxy Plugin
lebalz Oct 10, 2025
008914f
set redirectURI
lebalz Oct 10, 2025
f288b37
rm
lebalz Oct 10, 2025
08457f5
set betterauth url
lebalz Oct 10, 2025
38ab82d
use ba
lebalz Oct 10, 2025
42f34ea
set cp
lebalz Oct 10, 2025
2bfa4f3
fix redirect url
lebalz Oct 10, 2025
cf16303
setup logger
lebalz Oct 10, 2025
4608c78
rm redirect
lebalz Oct 10, 2025
d2329dc
rm
lebalz Oct 10, 2025
4df442a
proxy
lebalz Oct 10, 2025
c58c5d7
us csdc
lebalz Oct 10, 2025
a3a13de
debug logs
lebalz Oct 10, 2025
bba206c
sdf
lebalz Oct 10, 2025
5c521fd
ensure domain
lebalz Oct 10, 2025
4d3c2b0
update
lebalz Oct 10, 2025
5eefd5a
explicitely set cors
lebalz Oct 11, 2025
0a7ee9c
configure morgan
lebalz Oct 11, 2025
bea11bf
fp
lebalz Oct 11, 2025
82fe2bb
query
lebalz Oct 11, 2025
f46422b
rd
lebalz Oct 11, 2025
dbd6734
try
lebalz Oct 11, 2025
3fa2833
optimize
lebalz Oct 11, 2025
651e4fb
update
lebalz Oct 11, 2025
89320ab
try setting for deploy preview
lebalz Oct 11, 2025
5c3e8a6
tmp
lebalz Oct 12, 2025
19fc940
fix escaping
lebalz Oct 12, 2025
f116613
no crossSubDomain
lebalz Oct 12, 2025
e1d4ca9
disable csrf
lebalz Oct 12, 2025
ca928c2
re-enable csd
lebalz Oct 12, 2025
eea8213
rm
lebalz Oct 12, 2025
c5832bd
csrf
lebalz Oct 12, 2025
c92e673
rm cs
lebalz Oct 12, 2025
6eda2bd
add proxy
lebalz Oct 12, 2025
5d1029a
fix cb
lebalz Oct 12, 2025
7c656ea
undo
lebalz Oct 12, 2025
b60faab
add gh
lebalz Oct 12, 2025
4fead42
samesit cookie
lebalz Oct 12, 2025
6577558
configure usernamePw Login
lebalz Oct 12, 2025
5bd4a6f
session token cookie config
lebalz Oct 12, 2025
5ad4618
setup account linking
lebalz Oct 12, 2025
7fa99d3
fix camel-case
lebalz Oct 13, 2025
46492c6
add link-pw route
lebalz Oct 13, 2025
591bdb6
set default name
lebalz Oct 13, 2025
d34eb32
fix import
lebalz Oct 13, 2025
8d5a70b
fix import
lebalz Oct 13, 2025
44eef50
fix imports
lebalz Oct 13, 2025
8bb462d
expose socketIo server in it's own scope
lebalz Oct 13, 2025
e421e35
cleanup
lebalz Oct 13, 2025
61355ce
fix type-error
lebalz Oct 13, 2025
7ca35c8
remove unused sso plugin
lebalz Oct 14, 2025
9fa718c
use prisma config file
lebalz Oct 14, 2025
ddfd15f
update workflow
lebalz Oct 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"env": {
"es2021": true,
"node": true
},
"extends": ["prettier"],
"plugins": ["prettier", "@typescript-eslint"],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"prettier/prettier": [
"error",
{
"arrowParens": "always",
"bracketSpacing": true,
"bracketSameLine": false,
"printWidth": 110,
"proseWrap": "never",
"singleQuote": true,
"trailingComma": "none",
"tabWidth": 4
}
]
},
"parser": "@typescript-eslint/parser"
}
2 changes: 1 addition & 1 deletion .github/workflows/prettier-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '>=22.11'
node-version: '>=22.15'

- name: Install dependencies
run: yarn install
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ node_modules
docs/prisma/**/*
docs/*.svg
dist/
build/
# Sentry Config File
.sentryclirc

*.dump
src/generated/prisma
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
"singleQuote": true,
"trailingComma": "none",
"tabWidth": 4
}
}
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,16 +296,17 @@ dokku letsencrypt:enable dev-teaching-api
## when it succeeds, re-enable the cloudflare proxy for domain.tld...
```

### Speed Improvements
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`.

## Troubleshooting
## Dump from production

> [!Caution]
> Authentication Error: When your API can not authenticate requests
> - set the debug level in authConfig to 'info' and check the logs
> - 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` !!)
```bash
# inside shell of VSCode DevContainer (with configured dokku git remote)
dokku postgres:export dev-teaching-api > tdev-backup.dump
pg_restore -h localhost --verbose --clean --no-owner --no-privileges -U postgres -d teaching_api < tdev-backup.dump
# when ai-pr was once merged/deployed to the db, run `delete from _prisma_migrations where migration_name ilike '%_ai_%';`
```

## Speed Improvements
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`.

## CMS

Expand Down
54 changes: 54 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { defineConfig } from 'eslint/config';
import prettier from 'eslint-plugin-prettier';
import typescriptEslint from '@typescript-eslint/eslint-plugin';
import globals from 'globals';
import tsParser from '@typescript-eslint/parser';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import js from '@eslint/js';
import { FlatCompat } from '@eslint/eslintrc';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all
});

export default defineConfig([
{
extends: compat.extends('prettier'),

plugins: {
prettier,
'@typescript-eslint': typescriptEslint
},

languageOptions: {
globals: {
...globals.node
},

parser: tsParser,
ecmaVersion: 'latest',
sourceType: 'module'
},

rules: {
'prettier/prettier': [
'error',
{
arrowParens: 'always',
bracketSpacing: true,
bracketSameLine: false,
printWidth: 110,
proseWrap: 'never',
singleQuote: true,
trailingComma: 'none',
tabWidth: 4
}
]
}
}
]);
61 changes: 31 additions & 30 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,65 +1,66 @@
{
"name": "teaching-website-backend",
"version": "1.0.0",
"main": "index.js",
"main": "server.js",
"repository": "https://github.com/GBSL-Informatik/teaching-website-backend.git",
"author": "GBSL Informatik",
"license": "CC-BY-SA",
"license": "MIT",
"scripts": {
"build": "yarn run prisma generate && tsc --build ./tsconfig.build.json && (yarn sentry:sourcemaps || true)",
"start": "node -r dotenv/config ./dist/src/server.js",
"dev": "dotenv -- nodemon src/server.ts",
"dummy:run": "ts-node -r dotenv/config ./bin/dummy.ts",
"dev": "cross-env NODE_ENV=development nodemon -r tsconfig-paths/register --exec ts-node ./src/server.ts --files",
"build": "yarn run prisma generate && tsc --build ./tsconfig.build.json",
"start": "cross-env NODE_ENV=production node ./dist/src/server.js",
"lint": "eslint . --ignore-pattern node_modules --fix",
"format": "prettier --write ./**/*.{ts,json}",
"format:check": "prettier --check ./**/*.{ts,json}",
"db:migrate": "yarn prisma migrate deploy",
"db:migrate:dev": "yarn prisma migrate dev",
"db:seed": "yarn prisma db seed",
"db:reset": "dotenv -- ts-node prisma/reset.ts",
"db:recreate": "yarn run db:reset && yarn run db:migrate && yarn run db:seed",
"format": "prettier --write .",
"format:check": "prettier --check .",
"sentry:sourcemaps": "sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_PROJECT ./dist && sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_PROJECT ./dist"
},
"dependencies": {
"@prisma/adapter-pg": "^6.15.0",
"@prisma/client": "^6.15.0",
"@better-auth/sso": "^1.3.26",
"@prisma/adapter-pg": "^6.16.2",
"@prisma/client": "^6.16.2",
"@sentry/cli": "^2.52.0",
"@sentry/node": "^10.8.0",
"connect-pg-simple": "^9.0.1",
"better-auth": "^1.3.27",
"cors": "^2.8.5",
"cross-env": "^10.0.0",
"dotenv": "^17.2.2",
"es-toolkit": "^1.39.10",
"express": "^4.19.2",
"express-session": "^1.18.0",
"express": "^5.1.0",
"global": "^4.4.0",
"morgan": "^1.10.0",
"passport": "^0.7.0",
"passport-azure-ad": "^4.3.5",
"socket.io": "^4.8.1",
"winston": "^3.13.0"
},
"prisma": {
"schema": "./prisma/schema.prisma",
"seed": "dotenv -- ts-node prisma/seed.ts",
"reset": "dotenv -- ts-node prisma/reset.ts"
},
"devDependencies": {
"@mermaid-js/mermaid-cli": "^10.9.1",
"@types/connect-pg-simple": "^7.0.3",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/express": "^5.0.3",
"@types/morgan": "^1.9.9",
"@types/node": "^20.14.6",
"@types/passport-azure-ad": "^4.3.6",
"@typescript-eslint/eslint-plugin": "^8.44.1",
"@typescript-eslint/parser": "^8.44.1",
"dotenv-cli": "^7.4.2",
"nodemon": "^3.1.3",
"prettier": "^3.3.2",
"prisma": "^6.15.0",
"eslint": "^9.36.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.4",
"nodemon": "^3.1.10",
"prettier": "^3.6.2",
"prisma": "^6.17.1",
"prisma-dbml-generator": "^0.12.0",
"prisma-docs-generator": "^0.8.0",
"prisma-erd-generator": "^2.0.4",
"prisma-erd-generator": "^2.1.0",
"ts-node": "^10.9.2",
"typescript": "^5.5.4"
"tsc-alias": "^1.8.16",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.9.2",
"typescript-transform-paths": "^3.5.5"
},
"engines": {
"node": "^22.11.0"
"node": "^22.15.0"
}
}
}
14 changes: 14 additions & 0 deletions prisma.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import 'dotenv/config';
import path from 'node:path';

import type { PrismaConfig } from 'prisma';

export default {
experimental: {
adapter: true
},
migrations: {
seed: 'dotenv -- ts-node prisma/seed.ts'
}
// now you can use process.env variables
} satisfies PrismaConfig;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
Warnings:

- You are about to drop the `sessions` table. If the table is not empty, all the data it contains will be lost.

*/
-- DropTable
DROP TABLE "public"."sessions";
101 changes: 101 additions & 0 deletions prisma/migrations/20251005093734_migrate_to_better_auth/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
Warnings:

- 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.

*/
-- AlterTable
ALTER TABLE "public"."users"
ADD COLUMN "ban_expires" TIMESTAMP(3),
ADD COLUMN "ban_reason" TEXT,
ADD COLUMN "banned" BOOLEAN DEFAULT false,
ADD COLUMN "email_verified" BOOLEAN NOT NULL DEFAULT false,
ADD COLUMN "image" TEXT,
ADD COLUMN "name" TEXT NOT NULL DEFAULT '',
ADD COLUMN "trole" TEXT NOT NULL DEFAULT 'student';

UPDATE "public"."users" SET "trole" = 'admin' WHERE "role" = 'ADMIN';
UPDATE "public"."users" SET "trole" = 'teacher' WHERE "role" = 'TEACHER';

ALTER TABLE "public"."users"
DROP COLUMN "role";

ALTER TABLE "public"."users"
ADD COLUMN "role" TEXT NOT NULL DEFAULT 'student';

UPDATE "public"."users" SET "role" = trole;
UPDATE "public"."users" SET "name" = CONCAT(first_name, ' ', last_name) WHERE name = '';

ALTER TABLE "public"."users"
DROP COLUMN "trole";

-- DropEnum
DROP TYPE "public"."Role";

-- CreateTable
CREATE TABLE "public"."sessions" (
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
"ip_address" TEXT,
"user_agent" TEXT,
"user_id" UUID NOT NULL,
"token" TEXT NOT NULL,
"expires_at" TIMESTAMP(3) NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"impersonated_by" UUID,

CONSTRAINT "sessions_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "public"."accounts" (
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
"account_id" TEXT NOT NULL,
"provider_id" TEXT NOT NULL,
"user_id" UUID NOT NULL,
"access_token" TEXT,
"refresh_token" TEXT,
"id_token" TEXT,
"expires_at" TIMESTAMP(3),
"password" TEXT,
"access_token_expires_at" TIMESTAMP(3),
"refresh_token_expires_at" TIMESTAMP(3),
"scope" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,

CONSTRAINT "accounts_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "public"."verifications" (
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
"identifier" TEXT NOT NULL,
"value" TEXT NOT NULL,
"expires_at" TIMESTAMP(3) NOT NULL,
"created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,

CONSTRAINT "verifications_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE UNIQUE INDEX "sessions_token_key" ON "public"."sessions"("token");

-- CreateIndex
CREATE INDEX "sessions_user_id_idx" ON "public"."sessions"("user_id");

-- CreateIndex
CREATE INDEX "sessions_user_id_token_idx" ON "public"."sessions"("user_id", "token");

-- CreateIndex
CREATE INDEX "accounts_user_id_idx" ON "public"."accounts"("user_id");

-- CreateIndex
CREATE INDEX "verifications_identifier_idx" ON "public"."verifications"("identifier");

-- AddForeignKey
ALTER TABLE "public"."sessions" ADD CONSTRAINT "sessions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "public"."accounts" ADD CONSTRAINT "accounts_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
Loading