chore: rewrite /login page for OAuth, write createUser for the database
This commit is contained in:
+27
-3
@@ -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')}`)
|
||||
|
||||
@@ -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
@@ -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() })
|
||||
|
||||
Reference in New Issue
Block a user