chore: rewrite /login page for OAuth, write createUser for the database

This commit is contained in:
2023-01-10 20:07:25 +01:00
parent 2901a1f899
commit 9ae74fa649
9 changed files with 61 additions and 55 deletions
+27 -3
View File
@@ -1,8 +1,11 @@
import { Router } from 'express'
import { AuthorizationCode } from 'simple-oauth2'
import fetch from 'node-fetch'
import { DatabaseConnection, getUser, createUser } from './db/database'
import { UserId } from '../shared/model'
import { SessionService } from './routes'
export function setupOauth(r: Router) {
export function setupOauth(r: Router, db: DatabaseConnection, sessions: SessionService) {
const config = {
client: {
id: process.env.OAUTH_CLIENT_ID ?? '',
@@ -55,8 +58,29 @@ export function setupOauth(r: Router) {
})
).json()
// TODO: call to db && login
return res.status(200).json(userInfo)
type UserInfo = { name: string; email: string }
// Parse user info into a sensible struct
const authUser = {
id: (userInfo as UserInfo).email.split('@')[0] as UserId,
fullName: (userInfo as UserInfo).name
.split(' ')
.map(s => s.substring(0, 1) + s.substring(1).toLowerCase())
.join(' '),
}
const user = await getUser(db, authUser.id)
if (!user) {
await createUser(db, {
id: authUser.id,
fullName: authUser.fullName,
role: 'student',
})
}
res.cookie('sid', sessions.createSession(authUser.id), { maxAge: 1000 * 60 * 60 * 24 * 7 })
return res.status(200).redirect('/')
} catch (error) {
console.error('Access Token Error', error.message)
return res.status(500).redirect(`/error?message=${encodeURIComponent('Autenticazione fallita')}`)
+7 -2
View File
@@ -2,7 +2,7 @@ import crypto from 'crypto'
import { readFile, writeFile, access, constants } from 'fs/promises'
import { MetadataProps as MetaProps, Problem, ProblemId, Solution, SolutionId, User } from '../../shared/model'
import { MetadataProps as MetaProps, Problem, ProblemId, Solution, SolutionId, User, UserId, UserRole } from '../../shared/model'
function once<T extends (...args: any) => any>(fn: T, message: string): T {
let flag = false
@@ -53,7 +53,7 @@ function createMutex(): Mutex {
return { lock }
}
type DatabaseConnection = {
export type DatabaseConnection = {
path: string
initialValue: Database
mu: Mutex
@@ -110,6 +110,11 @@ export const getUser: (db: DatabaseConnection, id: string) => Promise<User | nul
return state.users[id] ?? null
})
export const createUser: (db: DatabaseConnection, user: User) => Promise<void> = (db, user) =>
withDatabase(db, state => {
state.users[user.id] = user
})
//
// Problems
//
+19 -14
View File
@@ -40,11 +40,16 @@ import { initialDatabaseValue } from './db/example-data'
import { validateObjectKeys } from '../shared/utils'
import { setupOauth } from './auth'
export async function createApiRouter() {
type SessionId = Opaque<string, string, 'session'>
type SessionId = Opaque<string, string, 'session'>
export interface SessionService {
createSession(userId: UserId): SessionId
getUserForSession(sid: SessionId): UserId | null
}
export async function createApiRouter() {
const sessionStore: Record<SessionId, UserId> = {}
const sessions = {
const sessions: SessionService = {
createSession(userId: UserId) {
const sid = crypto.randomBytes(10).toString('hex') as SessionId
sessionStore[sid] = userId
@@ -73,7 +78,7 @@ export async function createApiRouter() {
const authRouter: Router = express.Router()
setupOauth(authRouter)
setupOauth(authRouter, db, sessions)
r.use('/auth', authRouter)
r.get('/api/status', (req, res) => {
@@ -84,18 +89,18 @@ export async function createApiRouter() {
res.json(await getRequestUser(req))
})
r.post('/api/login', async (req, res) => {
const { id, name } = req.body
// r.post('/api/login', async (req, res) => {
// const { id, name } = req.body
const user = await getUser(db, id)
if (!user) {
res.sendStatus(StatusCodes.FORBIDDEN)
return
}
// const user = await getUser(db, id)
// if (!user) {
// res.sendStatus(StatusCodes.FORBIDDEN)
// return
// }
res.cookie('sid', sessions.createSession(id), { maxAge: 1000 * 60 * 60 * 24 * 7 })
res.json({ status: 'ok' })
})
// res.cookie('sid', sessions.createSession(id), { maxAge: 1000 * 60 * 60 * 24 * 7 })
// res.json({ status: 'ok' })
// })
r.post('/api/logout', (req, res) => {
res.cookie('sid', '', { expires: new Date() })