feat(frontend): Added functionality to the frontend to log in.

This commit is contained in:
Gerald Schmittinger 2025-03-02 16:33:50 +01:00
parent 4a1edbb6ff
commit a28ec22f29
20 changed files with 395 additions and 33 deletions

View file

@ -6,6 +6,11 @@ DWENGO_DB_PASSWORD=postgres
DWENGO_DB_UPDATE=true
DWENGO_AUTH_STUDENT_URL=http://localhost:7080/realms/student
DWENGO_AUTH_STUDENT_CLIENT_ID=dwengo
DWENGO_AUTH_STUDENT_JWKS_ENDPOINT=http://localhost:7080/realms/student/protocol/openid-connect/certs
DWENGO_AUTH_TEACHER_URL=http://localhost:7080/realms/teacher
DWENGO_AUTH_TEACHER_CLIENT_ID=dwengo
DWENGO_AUTH_TEACHER_JWKS_ENDPOINT=http://localhost:7080/realms/teacher/protocol/openid-connect/certs
# Allow frontend from anywhere to access the backend (for testing purposes). Don't forget to remove this in production!
DWENGO_CORS_ALLOWED_ORIGINS=*

View file

@ -24,7 +24,9 @@
"jwks-rsa": "^3.1.0",
"uuid": "^11.1.0",
"js-yaml": "^4.1.0",
"@types/js-yaml": "^4.0.9"
"@types/js-yaml": "^4.0.9",
"cors": "^2.8.5",
"@types/cors": "^2.8.17"
},
"devDependencies": {
"@mikro-orm/cli": "^6.4.6",

View file

@ -10,13 +10,13 @@ import assignmentRouter from './routes/assignment.js';
import submissionRouter from './routes/submission.js';
import classRouter from './routes/class.js';
import questionRouter from './routes/question.js';
import loginRouter from './routes/login.js';
import authRouter from './routes/auth.js';
import {authenticateUser} from "./middleware/auth/auth";
import cors from "./middleware/cors";
const app: Express = express();
const port: string | number = getNumericEnvVar(EnvVars.Port);
// TODO Replace with Express routes
app.get('/', (_, res: Response) => {
res.json({
@ -25,6 +25,7 @@ app.get('/', (_, res: Response) => {
});
app.use(authenticateUser);
app.use(cors);
app.use('/student', studentRouter);
app.use('/group', groupRouter);
@ -32,8 +33,7 @@ app.use('/assignment', assignmentRouter);
app.use('/submission', submissionRouter);
app.use('/class', classRouter);
app.use('/question', questionRouter);
app.use('/login', loginRouter);
app.use('/auth', authRouter);
app.use('/theme', themeRoutes);
async function startServer() {

View file

@ -0,0 +1,33 @@
import {EnvVars, getEnvVar} from "../util/envvars";
type FrontendAuthConfig = {
student: FrontendIdpConfig,
teacher: FrontendIdpConfig
}
type FrontendIdpConfig = {
authority: string,
clientId: string,
scope: string,
responseType: string
}
const SCOPE = "openid profile email";
const RESPONSE_TYPE = "code";
export function getFrontendAuthConfig(): FrontendAuthConfig {
return {
student: {
authority: getEnvVar(EnvVars.IdpStudentUrl),
clientId: getEnvVar(EnvVars.IdpStudentClientId),
scope: SCOPE,
responseType: RESPONSE_TYPE
},
teacher: {
authority: getEnvVar(EnvVars.IdpTeacherUrl),
clientId: getEnvVar(EnvVars.IdpTeacherClientId),
scope: SCOPE,
responseType: RESPONSE_TYPE
},
};
}

View file

@ -58,7 +58,6 @@ const verifyJwtToken = expressjwt({
* Get an object with information about the authenticated user from a given authenticated request.
*/
function getAuthenticationInfo(req: AuthenticatedRequest): AuthenticationInfo | undefined {
console.log("hi");
if (!req.jwtPayload) {
return;
}

View file

@ -0,0 +1,6 @@
import cors from "cors";
import {EnvVars, getEnvVar} from "../util/envvars";
export default cors({
origin: getEnvVar(EnvVars.CorsAllowedOrigins).split(',')
});

View file

@ -0,0 +1,10 @@
import express from 'express'
import {getFrontendAuthConfig} from "../controllers/auth";
const router = express.Router();
// returns auth configuration for frontend
router.get('/config', (req, res) => {
res.json(getFrontendAuthConfig());
});
export default router;

View file

@ -1,14 +0,0 @@
import express from 'express'
const router = express.Router();
// returns login paths for IDP
router.get('/', (req, res) => {
res.json({
// dummy variables, needs to be changed
// with IDP endpoints
leerkracht: '/login-leerkracht',
leerling: '/login-leerling',
});
})
export default router

View file

@ -15,10 +15,13 @@ export const EnvVars: { [key: string]: EnvVar } = {
DbPassword: { key: DB_PREFIX + 'PASSWORD', required: true },
DbUpdate: { key: DB_PREFIX + 'UPDATE', defaultValue: false },
IdpStudentUrl: { key: STUDENT_IDP_PREFIX + 'URL', required: true },
IdpStudentClientId: { key: STUDENT_IDP_PREFIX + 'CLIENT_ID', required: true },
IdpStudentJwksEndpoint: { key: STUDENT_IDP_PREFIX + 'JWKS_ENDPOINT', required: true },
IdpTeacherUrl: { key: TEACHER_IDP_PREFIX + 'URL', required: true },
IdpTeacherClientId: { key: TEACHER_IDP_PREFIX + 'CLIENT_ID', required: true },
IdpTeacherJwksEndpoint: { key: TEACHER_IDP_PREFIX + 'JWKS_ENDPOINT', required: true },
IdpAudience: { key: IDP_PREFIX + 'AUDIENCE', defaultValue: 'account' }
IdpAudience: { key: IDP_PREFIX + 'AUDIENCE', defaultValue: 'account' },
CorsAllowedOrigins: { key: PREFIX + 'CORS_ALLOWED_ORIGINS', defaultValue: ''}
} as const;
/**