merge: fixed merge conflicts with dev
This commit is contained in:
commit
faa2f58145
165 changed files with 3948 additions and 3282 deletions
|
@ -1,9 +1,11 @@
|
|||
import { UnauthorizedException } from '../exceptions/unauthorized-exception.js';
|
||||
import { getLogger } from '../logging/initalize.js';
|
||||
import { AuthenticatedRequest } from '../middleware/auth/authenticated-request.js';
|
||||
import { envVars, getEnvVar } from '../util/envVars.js';
|
||||
import {AuthenticatedRequest} from "../middleware/auth/authenticated-request";
|
||||
import {createStudent} from "../services/students";
|
||||
import {createOrUpdateStudent, createStudent} from "../services/students";
|
||||
import {AuthenticationInfo} from "../middleware/auth/authentication-info";
|
||||
import {Request, Response} from "express";
|
||||
import {createTeacher} from "../services/teachers";
|
||||
import {createOrUpdateTeacher, createTeacher} from "../services/teachers";
|
||||
|
||||
interface FrontendIdpConfig {
|
||||
authority: string;
|
||||
|
@ -20,7 +22,9 @@ interface FrontendAuthConfig {
|
|||
const SCOPE = 'openid profile email';
|
||||
const RESPONSE_TYPE = 'code';
|
||||
|
||||
function getFrontendAuthConfig(): FrontendAuthConfig {
|
||||
const logger = getLogger();
|
||||
|
||||
export function getFrontendAuthConfig(): FrontendAuthConfig {
|
||||
return {
|
||||
student: {
|
||||
authority: getEnvVar(envVars.IdpStudentUrl),
|
||||
|
@ -59,3 +63,24 @@ export async function handleHello(req: AuthenticatedRequest): Promise<void> {
|
|||
}, true);
|
||||
}
|
||||
}
|
||||
|
||||
export async function postHelloHandler(req: AuthenticatedRequest, res: Response): Promise<void> {
|
||||
const auth = req.auth;
|
||||
if (!auth) {
|
||||
throw new UnauthorizedException('Cannot say hello when not authenticated.');
|
||||
}
|
||||
const userData = {
|
||||
id: auth.username,
|
||||
username: auth.username,
|
||||
firstName: auth.firstName ?? '',
|
||||
lastName: auth.lastName ?? '',
|
||||
};
|
||||
if (auth.accountType === 'student') {
|
||||
await createOrUpdateStudent(userData);
|
||||
logger.debug(`Synchronized student ${userData.username} with IDP`);
|
||||
} else {
|
||||
await createOrUpdateTeacher(userData);
|
||||
logger.debug(`Synchronized teacher ${userData.username} with IDP`);
|
||||
}
|
||||
res.status(200).send({ message: 'Welcome!' });
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@ import { createGroup, deleteGroup, getAllGroups, getGroup, getGroupSubmissions,
|
|||
import { GroupDTO } from '@dwengo-1/common/interfaces/group';
|
||||
import { requireFields } from './error-helper.js';
|
||||
import { BadRequestException } from '../exceptions/bad-request-exception.js';
|
||||
import { EntityDTO } from '@mikro-orm/core';
|
||||
import { Group } from '../entities/assignments/group.entity.js';
|
||||
|
||||
function checkGroupFields(classId: string, assignmentId: number, groupId: number): void {
|
||||
requireFields({ classId, assignmentId, groupId });
|
||||
|
@ -35,7 +33,11 @@ export async function putGroupHandler(req: Request, res: Response): Promise<void
|
|||
const groupId = parseInt(req.params.groupid);
|
||||
checkGroupFields(classId, assignmentId, groupId);
|
||||
|
||||
const group = await putGroup(classId, assignmentId, groupId, req.body as Partial<EntityDTO<Group>>);
|
||||
// Only members field can be changed
|
||||
const members = req.body.members;
|
||||
requireFields({ members });
|
||||
|
||||
const group = await putGroup(classId, assignmentId, groupId, { members } as Partial<GroupDTO>);
|
||||
|
||||
res.json({ group });
|
||||
}
|
||||
|
@ -69,8 +71,8 @@ export async function getAllGroupsHandler(req: Request, res: Response): Promise<
|
|||
export async function createGroupHandler(req: Request, res: Response): Promise<void> {
|
||||
const classid = req.params.classid;
|
||||
const assignmentId = Number(req.params.assignmentid);
|
||||
|
||||
requireFields({ classid, assignmentId });
|
||||
const members = req.body.members;
|
||||
requireFields({ classid, assignmentId, members });
|
||||
|
||||
if (isNaN(assignmentId)) {
|
||||
throw new BadRequestException('Assignment id must be a number');
|
||||
|
|
|
@ -3,13 +3,10 @@ import { themes } from '../data/themes.js';
|
|||
import { FALLBACK_LANG } from '../config.js';
|
||||
import learningPathService from '../services/learning-paths/learning-path-service.js';
|
||||
import { Language } from '@dwengo-1/common/util/language';
|
||||
import {
|
||||
PersonalizationTarget,
|
||||
personalizedForGroup,
|
||||
personalizedForStudent,
|
||||
} from '../services/learning-paths/learning-path-personalization-util.js';
|
||||
import { BadRequestException } from '../exceptions/bad-request-exception.js';
|
||||
import { NotFoundException } from '../exceptions/not-found-exception.js';
|
||||
import { Group } from '../entities/assignments/group.entity.js';
|
||||
import { getAssignmentRepository, getGroupRepository } from '../data/repositories.js';
|
||||
|
||||
/**
|
||||
* Fetch learning paths based on query parameters.
|
||||
|
@ -20,20 +17,20 @@ export async function getLearningPaths(req: Request, res: Response): Promise<voi
|
|||
const searchQuery = req.query.search as string;
|
||||
const language = (req.query.language as string) || FALLBACK_LANG;
|
||||
|
||||
const forStudent = req.query.forStudent as string;
|
||||
const forGroupNo = req.query.forGroup as string;
|
||||
const assignmentNo = req.query.assignmentNo as string;
|
||||
const classId = req.query.classId as string;
|
||||
|
||||
let personalizationTarget: PersonalizationTarget | undefined;
|
||||
let forGroup: Group | undefined;
|
||||
|
||||
if (forStudent) {
|
||||
personalizationTarget = await personalizedForStudent(forStudent);
|
||||
} else if (forGroupNo) {
|
||||
if (forGroupNo) {
|
||||
if (!assignmentNo || !classId) {
|
||||
throw new BadRequestException('If forGroupNo is specified, assignmentNo and classId must also be specified.');
|
||||
}
|
||||
personalizationTarget = await personalizedForGroup(classId, parseInt(assignmentNo), parseInt(forGroupNo));
|
||||
const assignment = await getAssignmentRepository().findByClassIdAndAssignmentId(classId, parseInt(assignmentNo));
|
||||
if (assignment) {
|
||||
forGroup = (await getGroupRepository().findByAssignmentAndGroupNumber(assignment, parseInt(forGroupNo))) ?? undefined;
|
||||
}
|
||||
}
|
||||
|
||||
let hruidList;
|
||||
|
@ -48,18 +45,13 @@ export async function getLearningPaths(req: Request, res: Response): Promise<voi
|
|||
throw new NotFoundException(`Theme "${themeKey}" not found.`);
|
||||
}
|
||||
} else if (searchQuery) {
|
||||
const searchResults = await learningPathService.searchLearningPaths(searchQuery, language as Language, personalizationTarget);
|
||||
const searchResults = await learningPathService.searchLearningPaths(searchQuery, language as Language, forGroup);
|
||||
res.json(searchResults);
|
||||
return;
|
||||
} else {
|
||||
hruidList = themes.flatMap((theme) => theme.hruids);
|
||||
}
|
||||
|
||||
const learningPaths = await learningPathService.fetchLearningPaths(
|
||||
hruidList,
|
||||
language as Language,
|
||||
`HRUIDs: ${hruidList.join(', ')}`,
|
||||
personalizationTarget
|
||||
);
|
||||
const learningPaths = await learningPathService.fetchLearningPaths(hruidList, language as Language, `HRUIDs: ${hruidList.join(', ')}`, forGroup);
|
||||
res.json(learningPaths.data);
|
||||
}
|
||||
|
|
|
@ -17,15 +17,18 @@ export async function getSubmissionsHandler(req: Request, res: Response): Promis
|
|||
const lang = languageMap[req.query.language as string] || Language.Dutch;
|
||||
const version = parseInt(req.query.version as string) ?? 1;
|
||||
|
||||
const submissions = await getSubmissionsForLearningObjectAndAssignment(
|
||||
const forGroup = req.query.forGroup as string | undefined;
|
||||
|
||||
const submissions: SubmissionDTO[] = await getSubmissionsForLearningObjectAndAssignment(
|
||||
loHruid,
|
||||
lang,
|
||||
version,
|
||||
req.query.classId as string,
|
||||
parseInt(req.query.assignmentId as string)
|
||||
parseInt(req.query.assignmentId as string),
|
||||
forGroup ? parseInt(forGroup) : undefined
|
||||
);
|
||||
|
||||
res.json(submissions);
|
||||
res.json({ submissions });
|
||||
}
|
||||
|
||||
export async function getSubmissionHandler(req: Request, res: Response): Promise<void> {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Request, Response } from 'express';
|
||||
import { requireFields } from './error-helper';
|
||||
import { createInvitation, deleteInvitation, getAllInvitations, getInvitation, updateInvitation } from '../services/teacher-invitations';
|
||||
import { requireFields } from './error-helper.js';
|
||||
import { createInvitation, deleteInvitation, getAllInvitations, getInvitation, updateInvitation } from '../services/teacher-invitations.js';
|
||||
import { TeacherInvitationData } from '@dwengo-1/common/interfaces/teacher-invitation';
|
||||
import {ConflictException} from "../exceptions/conflict-exception";
|
||||
|
||||
|
@ -45,7 +45,7 @@ export async function updateInvitationHandler(req: Request, res: Response): Prom
|
|||
const sender = req.body.sender;
|
||||
const receiver = req.body.receiver;
|
||||
const classId = req.body.class;
|
||||
req.body.accepted = req.body.accepted !== 'false';
|
||||
req.body.accepted = req.body.accepted !== false;
|
||||
requireFields({ sender, receiver, classId });
|
||||
|
||||
const data = req.body as TeacherInvitationData;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue