diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index 03d9549..832ccb8 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -2,5 +2,6 @@
+
\ No newline at end of file
diff --git a/backend/src/routes/oauth2/authorize.ts b/backend/src/routes/oauth2/authorize.ts
index d92cd78..a53089a 100644
--- a/backend/src/routes/oauth2/authorize.ts
+++ b/backend/src/routes/oauth2/authorize.ts
@@ -3,7 +3,8 @@ import { nanoid } from 'nanoid';
import { scopes } from '../../constants';
import database from '../../database/database';
import { ParamError, ScopeError } from '../../errors';
-import type { MyFastifyInstance } from '../../types';
+import type { MyFastifyInstance, StudentsMode } from '../../types';
+
import {
getSessionData, isObject, parseScopeParam, validateOptionalParam, validateParam,
} from '../../utils';
@@ -39,22 +40,30 @@ export default function registerAuthorize(server: MyFastifyInstance): void {
try {
validateParam('response_type', request.query.response_type);
if (request.query.response_type === 'code') {
- const requestedScopes = _.uniq(parseScopeParam('scope', request.query.scope));
- requestedScopes.forEach((scope) => {
- if (!scopes.includes(scope)) {
- throw new ScopeError(`Unknown scope ${scope}`);
- }
- });
+ validateParam('students_mode', request.query.students_mode);
validateOptionalParam('state', request.query.state);
validateOptionalParam('code_challenge', request.query.code_challenge);
validateOptionalParam('code_challenge_method', request.query.code_challenge_method);
const codeChallengeMethod = request.query.code_challenge_method ?? 'plain';
if (codeChallengeMethod !== 'plain' && codeChallengeMethod !== 'S256') {
- await reply.redirect(`${request.query.redirect_uri}?error=invalid_request&error_description=${encodeURIComponent('code_challenge_method should be either plain or S256')}`);
- return;
+ throw new ParamError('code_challenge_method should be either "plain" or "S256"');
}
+ if (
+ !['none', 'one', 'many'].includes(request.query.students_mode)
+ ) {
+ throw new ParamError('students_mode should be either "none", "one" or "many"');
+ }
+ const studentsMode = request.query.students_mode as StudentsMode;
+
+ const requestedScopes = _.uniq(parseScopeParam('scope', request.query.scope));
+ requestedScopes.forEach((scope) => {
+ if (!scopes.includes(scope)) {
+ throw new ScopeError(`Unknown scope ${scope}`);
+ }
+ });
+
const promptId = nanoid(12);
const sessionData = getSessionData(request.session);
@@ -67,6 +76,7 @@ export default function registerAuthorize(server: MyFastifyInstance): void {
method: codeChallengeMethod,
value: request.query.code_challenge,
},
+ studentsMode,
});
await reply.redirect(`/authenticate-prompt?prompt_id=${promptId}`);
diff --git a/backend/src/routes/website-api/models/prompt-info.ts b/backend/src/routes/website-api/models/prompt-info.ts
index 0fc787e..36898cb 100644
--- a/backend/src/routes/website-api/models/prompt-info.ts
+++ b/backend/src/routes/website-api/models/prompt-info.ts
@@ -1,4 +1,5 @@
import { Field, ObjectType } from 'type-graphql';
+import { StudentsMode } from '../../../types';
import PromptInfoApplication from './prompt-info-application';
@ObjectType()
@@ -12,6 +13,9 @@ export default class PromptInfo {
@Field(() => String)
public clientId!: string;
+ @Field(() => StudentsMode)
+ public studentsMode!: StudentsMode;
+
@Field(() => PromptInfoApplication)
public application!: PromptInfoApplication;
}
diff --git a/backend/src/routes/website-api/resolvers/prompt-info-resolver.ts b/backend/src/routes/website-api/resolvers/prompt-info-resolver.ts
index 96df930..962fb39 100644
--- a/backend/src/routes/website-api/resolvers/prompt-info-resolver.ts
+++ b/backend/src/routes/website-api/resolvers/prompt-info-resolver.ts
@@ -22,6 +22,7 @@ export default class PromptInfoResolver implements ResolverInterface
id: promptId,
clientId: prompt.clientId,
scopes: prompt.scopes,
+ studentsMode: prompt.studentsMode,
};
}
diff --git a/backend/src/types.ts b/backend/src/types.ts
index c505fd4..753b14f 100644
--- a/backend/src/types.ts
+++ b/backend/src/types.ts
@@ -1,8 +1,19 @@
import type {
FastifyInstance, FastifyRequest, RawReplyDefaultExpression, RawRequestDefaultExpression, RawServerDefault,
} from 'fastify';
+import { registerEnumType } from 'type-graphql';
import type SessionData from './session-data';
+export enum StudentsMode {
+ None = 'none',
+ One = 'one',
+ Many = 'many',
+}
+
+registerEnumType(StudentsMode, {
+ name: 'StudentsMode',
+});
+
export interface Prompt {
clientId: string;
redirectUri: string;
@@ -12,6 +23,7 @@ export interface Prompt {
value: string;
method: 'plain' | 'S256';
};
+ studentsMode: StudentsMode;
loginInfo?: {
host: string;
username: string;