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