import Fastify from 'fastify'; import * as Jose from 'jose'; import { v4 as uuidv4 } from 'uuid' const IDENTITY_API_LANDING_MESSAGE = 'identity-api v1.0.0'; const JWT_SECRET = new TextEncoder().encode( 'cc7e0d44fd473002f1c42167459001140ec6389b7353f8088f4d9a95f2f596f2', ) const JWT_ALG = 'HS256' let users = { 'jane@identity.net': { uid: '005d6417-a23c-48bd-b348-eafeae649b94', password: '12345678901234567890', name: 'Jane Doe', } } const fastify = Fastify({ logger: true, }) fastify.get('/', async (request, reply) => { return IDENTITY_API_LANDING_MESSAGE; }) fastify.get('/auth/account', { async handler(request, reply) { let jwt = request.headers['authorization'].replace('Bearer', '').trim() let { payload } = await Jose.jwtVerify(jwt, JWT_SECRET) let user = users[payload.email] user.password = undefined return user }, schema: { headers: { type: 'object', properties: { authorization: { type: 'string' }, }, }, }, }) fastify.post('/auth/login', { async handler(request, reply) { let user = users[request.body.email]; if (user != null && user.password == request.body.password) { let token = await new Jose.SignJWT({ uid: user.uid, email: request.body.email, name: user.name, }) .setProtectedHeader({ alg: JWT_ALG }) .setIssuedAt() .setExpirationTime('4w') .sign(JWT_SECRET); return { token, } } reply.code(400); return { error: 'invalid credentials' } }, schema: { body: { type: 'object', properties: { email: { type: 'string' }, password: { type: 'string' }, }, }, }, }) fastify.post('/auth/register', { async handler(request, reply) { if (users[request.body.email] == null) { users[request.body.email] = { uid: uuidv4(), password: request.body.password, name: request.body.name, } let user = users[request.body.email] let token = await new Jose.SignJWT({ uid: user.uid, email: request.body.email, name: user.name, }) .setProtectedHeader({ alg: JWT_ALG }) .setIssuedAt() .setExpirationTime('4w') .sign(JWT_SECRET); return { token } } reply.code(400); return { error: 'invalid data' } }, schema: { body: { type: 'object', properties: { name: { type: 'string' }, email: { type: 'string' }, password: { type: 'string' }, }, }, }, }) fastify.listen({ port: 3000 })