Add students_mode field

This commit is contained in:
Dominik Korsa 2021-01-18 13:26:09 +01:00
parent 9007437bd3
commit 85c94b3516
No known key found for this signature in database
GPG key ID: 546F986F71A6FE6E
5 changed files with 37 additions and 9 deletions

View file

@ -2,5 +2,6 @@
<profile version="1.0"> <profile version="1.0">
<option name="myName" value="Project Default" /> <option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ExceptionCaughtLocallyJS" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
</profile> </profile>
</component> </component>

View file

@ -3,7 +3,8 @@ import { nanoid } from 'nanoid';
import { scopes } from '../../constants'; import { scopes } from '../../constants';
import database from '../../database/database'; import database from '../../database/database';
import { ParamError, ScopeError } from '../../errors'; import { ParamError, ScopeError } from '../../errors';
import type { MyFastifyInstance } from '../../types'; import type { MyFastifyInstance, StudentsMode } from '../../types';
import { import {
getSessionData, isObject, parseScopeParam, validateOptionalParam, validateParam, getSessionData, isObject, parseScopeParam, validateOptionalParam, validateParam,
} from '../../utils'; } from '../../utils';
@ -39,22 +40,30 @@ export default function registerAuthorize(server: MyFastifyInstance): void {
try { try {
validateParam('response_type', request.query.response_type); validateParam('response_type', request.query.response_type);
if (request.query.response_type === 'code') { if (request.query.response_type === 'code') {
const requestedScopes = _.uniq(parseScopeParam('scope', request.query.scope)); validateParam('students_mode', request.query.students_mode);
requestedScopes.forEach((scope) => {
if (!scopes.includes(scope)) {
throw new ScopeError(`Unknown scope ${scope}`);
}
});
validateOptionalParam('state', request.query.state); validateOptionalParam('state', request.query.state);
validateOptionalParam('code_challenge', request.query.code_challenge); validateOptionalParam('code_challenge', request.query.code_challenge);
validateOptionalParam('code_challenge_method', request.query.code_challenge_method); validateOptionalParam('code_challenge_method', request.query.code_challenge_method);
const codeChallengeMethod = request.query.code_challenge_method ?? 'plain'; const codeChallengeMethod = request.query.code_challenge_method ?? 'plain';
if (codeChallengeMethod !== 'plain' && codeChallengeMethod !== 'S256') { 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')}`); throw new ParamError('code_challenge_method should be either "plain" or "S256"');
return;
} }
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 promptId = nanoid(12);
const sessionData = getSessionData(request.session); const sessionData = getSessionData(request.session);
@ -67,6 +76,7 @@ export default function registerAuthorize(server: MyFastifyInstance): void {
method: codeChallengeMethod, method: codeChallengeMethod,
value: request.query.code_challenge, value: request.query.code_challenge,
}, },
studentsMode,
}); });
await reply.redirect(`/authenticate-prompt?prompt_id=${promptId}`); await reply.redirect(`/authenticate-prompt?prompt_id=${promptId}`);

View file

@ -1,4 +1,5 @@
import { Field, ObjectType } from 'type-graphql'; import { Field, ObjectType } from 'type-graphql';
import { StudentsMode } from '../../../types';
import PromptInfoApplication from './prompt-info-application'; import PromptInfoApplication from './prompt-info-application';
@ObjectType() @ObjectType()
@ -12,6 +13,9 @@ export default class PromptInfo {
@Field(() => String) @Field(() => String)
public clientId!: string; public clientId!: string;
@Field(() => StudentsMode)
public studentsMode!: StudentsMode;
@Field(() => PromptInfoApplication) @Field(() => PromptInfoApplication)
public application!: PromptInfoApplication; public application!: PromptInfoApplication;
} }

View file

@ -22,6 +22,7 @@ export default class PromptInfoResolver implements ResolverInterface<PromptInfo>
id: promptId, id: promptId,
clientId: prompt.clientId, clientId: prompt.clientId,
scopes: prompt.scopes, scopes: prompt.scopes,
studentsMode: prompt.studentsMode,
}; };
} }

View file

@ -1,8 +1,19 @@
import type { import type {
FastifyInstance, FastifyRequest, RawReplyDefaultExpression, RawRequestDefaultExpression, RawServerDefault, FastifyInstance, FastifyRequest, RawReplyDefaultExpression, RawRequestDefaultExpression, RawServerDefault,
} from 'fastify'; } from 'fastify';
import { registerEnumType } from 'type-graphql';
import type SessionData from './session-data'; import type SessionData from './session-data';
export enum StudentsMode {
None = 'none',
One = 'one',
Many = 'many',
}
registerEnumType(StudentsMode, {
name: 'StudentsMode',
});
export interface Prompt { export interface Prompt {
clientId: string; clientId: string;
redirectUri: string; redirectUri: string;
@ -12,6 +23,7 @@ export interface Prompt {
value: string; value: string;
method: 'plain' | 'S256'; method: 'plain' | 'S256';
}; };
studentsMode: StudentsMode;
loginInfo?: { loginInfo?: {
host: string; host: string;
username: string; username: string;