/* eslint-disable unicorn/no-null */ import * as Joi from "joi"; import * as Hapi from "@hapi/hapi"; import { ResponseToolkit, ResponseObject } from "@hapi/hapi"; export interface LinkAccountPayload { userId: string; providerType: string; providerId: string; providerAccountId: string; refreshToken: string; accessToken: string; accessTokenExpires?: null; } export const register = async ( server: Hapi.Server, opts: any, auth?: string ): Promise => { const { tags, basePath, validators } = opts; const { session, user, userId, profile } = validators; server.route([ { method: "POST", path: `${basePath}/createUser`, options: { auth, tags, validate: { payload: profile, }, async handler( request: Hapi.Request, h: ResponseToolkit ): Promise { const payload: TProfile = request.payload as TProfile; const r = await opts .nextAuthAdapterFactory(request) .createUser(payload); return h.response(r as object); }, description: "Create a user from a profile", }, }, { method: "GET", path: `${basePath}/getUser/{userId}`, options: { auth, tags, validate: { params: { userId, }, }, async handler( request: Hapi.Request, h: ResponseToolkit ): Promise { const id = request.params.userId; const r = await opts.nextAuthAdapterFactory(request).getUser(id); if (!r) return h.response().code(404); return h.response(r as object); }, description: "Get a user by id", }, }, { method: "GET", path: `${basePath}/getUserByEmail/{userEmail}`, options: { auth, tags, validate: { params: { userEmail: Joi.string().email(), }, }, async handler( request: Hapi.Request, h: ResponseToolkit ): Promise { const email = request.params.userEmail; const r = await opts .nextAuthAdapterFactory(request) .getUserByEmail(email); if (!r) return h.response().code(404); return h.response(r as object); }, description: "Get a user by email", }, }, { method: "GET", path: `${basePath}/getUserByProviderAccountId/{providerId}/{providerAccountId}`, options: { auth, tags, validate: { params: { providerId: Joi.string(), providerAccountId: Joi.string(), }, }, async handler( request: Hapi.Request, h: ResponseToolkit ): Promise { const { providerId, providerAccountId } = request.params; const r = await opts .nextAuthAdapterFactory(request) .getUserByProviderAccountId(providerId, providerAccountId); if (!r) return h.response().code(404); return h.response(r as object); }, description: "Get a user by provider id and provider account id", }, }, { method: "PUT", path: `${basePath}/updateUser`, options: { auth, tags, validate: { payload: user, }, async handler( request: Hapi.Request, h: ResponseToolkit ): Promise { const payload: TUser = request.payload as TUser; const r = await opts .nextAuthAdapterFactory(request) .updateUser(payload); if (!r) return h.response().code(404); return h.response(r as object); }, description: "Update a user's data", }, }, { method: "PUT", path: `${basePath}/linkAccount`, options: { auth, tags, validate: { payload: Joi.object({ userId, providerId: Joi.string(), providerType: Joi.string(), providerAccountId: Joi.string(), refreshToken: Joi.string().optional().allow(null), accessToken: Joi.string().optional().allow(null), accessTokenExpires: Joi.number().optional().allow(null), }).options({ presence: "required" }), }, async handler( request: Hapi.Request, h: ResponseToolkit ): Promise { const { userId, providerId, providerType, providerAccountId, refreshToken, accessToken, accessTokenExpires, } = request.payload as LinkAccountPayload; await opts .nextAuthAdapterFactory(request) .linkAccount( userId, providerId, providerType, providerAccountId, refreshToken, accessToken, accessTokenExpires ); return h.response().code(204); }, description: "Link a provider account with a user", }, }, { method: "POST", path: `${basePath}/createSession`, options: { auth, tags, validate: { payload: user, }, async handler( request: Hapi.Request, h: ResponseToolkit ): Promise { const payload: TUser = request.payload as TUser; const r = await opts .nextAuthAdapterFactory(request) .createSession(payload); return h.response(r as object); }, description: "Create a new session for a user", }, }, { method: "GET", path: `${basePath}/getSession/{sessionToken}`, options: { auth, tags, validate: { params: { sessionToken: Joi.string(), }, }, async handler( request: Hapi.Request, h: ResponseToolkit ): Promise { const token = request.params.sessionToken; const r = await opts .nextAuthAdapterFactory(request) .getSession(token); if (!r) return h.response().code(404); return h.response(r as object); }, description: "Get a session by its token", }, }, { method: "PUT", path: `${basePath}/updateSession`, options: { auth, tags, validate: { payload: session, }, async handler( request: Hapi.Request, h: ResponseToolkit ): Promise { const inputPayload = request.payload as any; const { expires } = inputPayload; const payload = { ...inputPayload, expires: new Date(expires), }; const force = Boolean(request.query.force); const r = await opts .nextAuthAdapterFactory(request) .updateSession(payload, force); if (!r) return h.response().code(204); return h.response(r as object); }, description: "Update a session for a user", }, }, { method: "DELETE", path: `${basePath}/deleteSession/{sessionToken}`, options: { auth, tags, validate: { params: { sessionToken: Joi.string(), }, }, async handler( request: Hapi.Request, h: ResponseToolkit ): Promise { const token = request.params.sessionToken; await opts.nextAuthAdapterFactory(request).deleteSession(token); return h.response().code(204); }, description: "Delete a user's session", }, }, ]); };