feat(dev): add compose files and dev-login bypass route
- compose.prod.yml: production stack with registry image, healthcheck, migration service - compose.test.yml: local test stack with source mount and LOCAL=true - routes/dev-login.ts: fake admin JWT login, only active when LOCAL=true - routes/_middleware.ts: expose /dev-login as public route Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
services:
|
||||
db:
|
||||
image: postgres:17-alpine
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASS}
|
||||
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
||||
POSTGRES_DB: ${POSTGRES_DB:-polympr}
|
||||
volumes:
|
||||
- db_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
|
||||
migrate:
|
||||
image: registry.docker.polytech.djalim.fr/polympr:latest
|
||||
command: node_modules/.bin/drizzle-kit migrate
|
||||
env_file: .env
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
|
||||
app:
|
||||
image: registry.docker.polytech.djalim.fr/polympr:latest
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "4430:443"
|
||||
env_file: .env
|
||||
depends_on:
|
||||
migrate:
|
||||
condition: service_completed_successfully
|
||||
|
||||
volumes:
|
||||
db_data:
|
||||
@@ -0,0 +1,49 @@
|
||||
services:
|
||||
db:
|
||||
image: postgres:17-alpine
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_PASSWORD: testpass
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_DB: polympr_test
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
|
||||
migrate:
|
||||
image: denoland/deno:alpine
|
||||
working_dir: /app
|
||||
volumes:
|
||||
- .:/app
|
||||
command: task migrate
|
||||
environment:
|
||||
POSTGRES_HOST: db
|
||||
POSTGRES_PORT: 5432
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASS: testpass
|
||||
POSTGRES_DB: polympr_test
|
||||
LOCAL: "true"
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
|
||||
app:
|
||||
image: denoland/deno:alpine
|
||||
working_dir: /app
|
||||
volumes:
|
||||
- .:/app
|
||||
command: run -A --unstable-ffi main.ts
|
||||
ports:
|
||||
- "4430:443"
|
||||
environment:
|
||||
POSTGRES_HOST: db
|
||||
POSTGRES_PORT: 5432
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASS: testpass
|
||||
POSTGRES_DB: polympr_test
|
||||
LOCAL: "true"
|
||||
depends_on:
|
||||
migrate:
|
||||
condition: service_completed_successfully
|
||||
@@ -10,6 +10,7 @@ const PUBLIC_ROUTES = [
|
||||
"/about",
|
||||
"/partials/about",
|
||||
"/contact",
|
||||
"/dev-login",
|
||||
];
|
||||
|
||||
const jwtKeyCache: Record<string, string> = {};
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import { FreshContext, Handlers } from "$fresh/server.ts";
|
||||
import { CasContent, LoginJWT, State } from "$root/defaults/interfaces.ts";
|
||||
import { createJwt } from "@popov/jwt";
|
||||
import { setCookie } from "$std/http/cookie.ts";
|
||||
import { getKey } from "$root/routes/_middleware.ts";
|
||||
|
||||
const FAKE_ADMIN: CasContent = {
|
||||
amuCampus: "local",
|
||||
amuComposante: "local",
|
||||
amuDateValidation: "",
|
||||
coGroup: "",
|
||||
eduPersonPrimaryAffiliation: "employee",
|
||||
eduPersonPrincipalName: "admin@local",
|
||||
mail: "admin@local",
|
||||
displayName: "Admin Local",
|
||||
givenName: "Admin",
|
||||
memberOf: [],
|
||||
sn: "Local",
|
||||
supannCivilite: "",
|
||||
supannEntiteAffectation: "",
|
||||
supannEtuAnneeInscription: "",
|
||||
supannEtuEtape: "",
|
||||
uid: "admin-local",
|
||||
};
|
||||
|
||||
export const handler: Handlers<null, State> = {
|
||||
async GET(_request: Request, _context: FreshContext<State, null>) {
|
||||
if (Deno.env.get("LOCAL") !== "true") {
|
||||
return new Response("Not available outside LOCAL mode.", { status: 403 });
|
||||
}
|
||||
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
const payload: LoginJWT = {
|
||||
iss: "PolyMPR",
|
||||
iat: now,
|
||||
exp: now + 0xe10,
|
||||
aud: "PolyMPR",
|
||||
user: FAKE_ADMIN,
|
||||
};
|
||||
|
||||
const token = await createJwt(payload, getKey(FAKE_ADMIN.uid));
|
||||
const headers = new Headers();
|
||||
setCookie(headers, { name: "sessionToken", value: token });
|
||||
headers.set("Location", "/apps");
|
||||
|
||||
return new Response(null, { status: 302, headers });
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user