/* eslint-disable unicorn/no-null */ import Toys from "@hapipal/toys"; import * as Joi from "joi"; import * as Hapi from "@hapi/hapi"; import { NextAuthPluginOptions } from "./types"; export const register = async ( server: Hapi.Server, opts: NextAuthPluginOptions, auth?: string ): Promise => { const withDefaults = Toys.withRouteDefaults({ options: { auth, tags: opts.tags, }, }); server.route([ withDefaults({ method: "POST", path: `${opts.basePath}/createUser`, options: { validate: { payload: opts.validators.profile, }, handler: async ( request: Hapi.Request, h: Hapi.Toolkit ): Promise => { const payload: TProfile = request.payload as TProfile; const r = await opts .nextAuthAdapterFactory(request) .createUser(payload); return h.response(r); }, description: "Create a user from a profile", }, }), withDefaults({ method: "GET", path: `${opts.basePath}/getUser/{userId}`, options: { validate: { params: { userId: opts.validators.userId, }, }, handler: async ( request: Hapi.Request, h: Hapi.Toolkit ): 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); }, description: "Get a user by id", }, }), withDefaults({ method: "GET", path: `${opts.basePath}/getUserByEmail/{userEmail}`, options: { validate: { params: { userEmail: Joi.string().email(), }, }, handler: async ( request: Hapi.Request, h: Hapi.Toolkit ): 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); }, description: "Get a user by email", }, }), withDefaults({ method: "GET", path: `${opts.basePath}/getUserByProviderAccountId/{providerId}/{providerAccountId}`, options: { validate: { params: { providerId: Joi.string(), providerAccountId: Joi.string(), }, }, handler: async ( request: Hapi.Request, h: Hapi.Toolkit ): 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); }, description: "Get a user by provider id and provider account id", }, }), withDefaults({ method: "PUT", path: `${opts.basePath}/updateUser`, options: { validate: { payload: opts.validators.user, }, handler: async ( request: Hapi.Request, h: Hapi.Toolkit ): 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); }, description: "Update a user's data", }, }), withDefaults({ method: "PUT", path: `${opts.basePath}/linkAccount`, options: { validate: { payload: Joi.object({ userId: opts.validators.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" }), }, handler: async ( request: Hapi.Request, h: Hapi.Toolkit ): Promise => { const { userId, providerId, providerType, providerAccountId, refreshToken, accessToken, accessTokenExpires, } = request.payload; 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", }, }), withDefaults({ method: "POST", path: `${opts.basePath}/createSession`, options: { validate: { payload: opts.validators.user, }, handler: async ( request: Hapi.Request, h: Hapi.Toolkit ): Promise => { const payload: TUser = request.payload as TUser; const r = await opts .nextAuthAdapterFactory(request) .createSession(payload); return h.response(r); }, description: "Create a new session for a user", }, }), withDefaults({ method: "GET", path: `${opts.basePath}/getSession/{sessionToken}`, options: { validate: { params: { sessionToken: Joi.string(), }, }, handler: async ( request: Hapi.Request, h: Hapi.Toolkit ): 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); }, description: "Get a session by its token", }, }), withDefaults({ method: "PUT", path: `${opts.basePath}/updateSession`, options: { validate: { payload: opts.validators.session, }, handler: async ( request: Hapi.Request, h: Hapi.Toolkit ): Promise => { const payload = { ...request.payload, expires: new Date(request.payload.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); }, description: "Update a session for a user", }, }), withDefaults({ method: "DELETE", path: `${opts.basePath}/deleteSession/{sessionToken}`, options: { validate: { params: { sessionToken: Joi.string(), }, }, handler: async ( request: Hapi.Request, h: Hapi.Toolkit ): Promise => { const token = request.params.sessionToken; await opts.nextAuthAdapterFactory(request).deleteSession(token); return h.response().code(204); }, description: "Delete a user's session", }, }), ]); };