From 43e86c70cdb84c681fdbf4bcb8847845b6ceef8c Mon Sep 17 00:00:00 2001 From: Dominik Korsa Date: Mon, 25 Jan 2021 14:25:34 +0100 Subject: [PATCH] Implement token generation --- backend/src/database/database.ts | 5 +++ backend/src/database/entities/token.ts | 48 ++++++++++++++++++++++++++ backend/src/routes/oauth2/token.ts | 31 +++++++++++++++-- backend/src/types.ts | 4 +++ backend/src/utils/token.ts | 0 5 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 backend/src/database/entities/token.ts delete mode 100644 backend/src/utils/token.ts diff --git a/backend/src/database/database.ts b/backend/src/database/database.ts index d8f8876..934434d 100644 --- a/backend/src/database/database.ts +++ b/backend/src/database/database.ts @@ -1,6 +1,7 @@ import type { Connection, Repository } from 'typeorm'; import { createConnection } from 'typeorm'; import Application from './entities/application'; +import Token from './entities/token'; import User from './entities/user'; class Database { @@ -10,6 +11,8 @@ class Database { public userRepo!: Repository; + public tokenRepo!: Repository; + public async connect(): Promise { this.connection = await createConnection({ type: 'mongodb', @@ -19,12 +22,14 @@ class Database { entities: [ Application, User, + Token, ], useUnifiedTopology: true, logging: false, }); this.applicationRepo = this.connection.getRepository(Application); this.userRepo = this.connection.getRepository(User); + this.tokenRepo = this.connection.getRepository(Token); } } diff --git a/backend/src/database/entities/token.ts b/backend/src/database/entities/token.ts new file mode 100644 index 0000000..cd44858 --- /dev/null +++ b/backend/src/database/entities/token.ts @@ -0,0 +1,48 @@ +import { nanoid } from 'nanoid'; +import type { ObjectID } from 'typeorm'; +import { + BaseEntity, Column, Entity, ObjectIdColumn, +} from 'typeorm'; + +@Entity() +export default class Token extends BaseEntity { + @ObjectIdColumn() + public _id!: ObjectID; + + @Column() + public tokenId!: string; + + @Column() + public creationDate!: Date; + + @Column() + public studentIds!: number[]; + + @Column() + public scopes!: string[]; + + @Column() + public clientId!: string; + + @Column() + public userId!: ObjectID; + + @Column() + public tokenSecret!: string; + + @Column() + public publicKey!: string; + + @Column() + public encryptedPassword!: string; + + @Column() + public encryptedSDK!: string; + + @Column() + public encryptedPrivateKey!: string; + + public static generateTokenId(): string { + return nanoid(20); + } +} diff --git a/backend/src/routes/oauth2/token.ts b/backend/src/routes/oauth2/token.ts index 967fc55..db32d5d 100644 --- a/backend/src/routes/oauth2/token.ts +++ b/backend/src/routes/oauth2/token.ts @@ -1,10 +1,12 @@ import type { FastifyReply } from 'fastify'; import { getCode, invalidateCode } from '../../codes'; import database from '../../database/database'; +import Token from '../../database/entities/token'; import { ParamError } from '../../errors'; -import type { CodeInfo, MyFastifyInstance } from '../../types'; +import type { CodeInfo, MyFastifyInstance, TokenContent } from '../../types'; import { + encryptSymmetrical, isObject, sha256, validateParam, } from '../../utils'; @@ -100,10 +102,33 @@ export default function registerToken(server: MyFastifyInstance): void { } } - // TODO: Generate and return token; + const tokenId = Token.generateTokenId(); + + const token = new Token(); + token.tokenId = tokenId; + token.creationDate = new Date(); + token.clientId = codeInfo.clientId; + token.scopes = codeInfo.scopes; + token.studentIds = codeInfo.studentIds; + token.tokenSecret = codeInfo.tokenSecret; + token.userId = codeInfo.userId; + token.encryptedPassword = codeInfo.encryptedPassword; + token.encryptedPrivateKey = codeInfo.encryptedPrivateKey; + token.encryptedSDK = codeInfo.encryptedSDK; + token.publicKey = codeInfo.publicKey; + + await database.tokenRepo.save(token); + + const content: TokenContent = { + tk: tokenKey, + }; invalidateCode(codeInfo.id); - await reply.code(500).send('Not implemented'); + await reply.code(200).send({ + access_token: `${tokenId}~${encryptSymmetrical(JSON.stringify(content), codeInfo.tokenSecret)}`, + token_type: 'bearer', + scope: codeInfo.scopes.join(' '), + }); return; } catch (error) { if (error instanceof ParamError) { diff --git a/backend/src/types.ts b/backend/src/types.ts index dab6d1c..44d7d9c 100644 --- a/backend/src/types.ts +++ b/backend/src/types.ts @@ -91,3 +91,7 @@ export interface CodeInfo { export interface CodeContent { tk: string; } + +export interface TokenContent { + tk: string; +} diff --git a/backend/src/utils/token.ts b/backend/src/utils/token.ts deleted file mode 100644 index e69de29..0000000