2024-06-13 20:00:45 +00:00
|
|
|
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 = {
|
2024-06-13 21:14:20 +00:00
|
|
|
'jane@identity.net': {
|
2024-06-13 20:00:45 +00:00
|
|
|
uid: '005d6417-a23c-48bd-b348-eafeae649b94',
|
2024-06-13 21:14:20 +00:00
|
|
|
password: '12345678901234567890',
|
|
|
|
name: 'Jane Doe',
|
2024-06-13 20:00:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const fastify = Fastify({
|
|
|
|
logger: true,
|
|
|
|
})
|
|
|
|
|
|
|
|
fastify.get('/', async (request, reply) => {
|
|
|
|
return IDENTITY_API_LANDING_MESSAGE;
|
|
|
|
})
|
|
|
|
|
2024-06-13 21:48:12 +00:00
|
|
|
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' },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2024-06-13 20:00:45 +00:00
|
|
|
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,
|
2024-06-13 21:48:12 +00:00
|
|
|
email: request.body.email,
|
2024-06-13 20:00:45 +00:00
|
|
|
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,
|
2024-06-13 21:48:12 +00:00
|
|
|
email: request.body.email,
|
2024-06-13 20:00:45 +00:00
|
|
|
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 })
|