Move packages/apps back
This commit is contained in:
parent
6eaaf8e9be
commit
5535d6b575
348 changed files with 0 additions and 0 deletions
232
apps/metamigo-frontend/lib/nextauth-adapter.ts
Normal file
232
apps/metamigo-frontend/lib/nextauth-adapter.ts
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
/* eslint-disable unicorn/no-null */
|
||||
import type { Adapter } from "next-auth/adapters";
|
||||
// @ts-expect-error: Missing export
|
||||
import type { AppOptions } from "next-auth";
|
||||
import * as Wreck from "@hapi/wreck";
|
||||
import * as Boom from "@hapi/boom";
|
||||
|
||||
import type { IAppConfig } from "config";
|
||||
|
||||
export interface Profile {
|
||||
name: string;
|
||||
email: string;
|
||||
emailVerified: string;
|
||||
userRole: string;
|
||||
avatar?: string;
|
||||
image?: string;
|
||||
createdBy: string;
|
||||
}
|
||||
|
||||
export type User = Profile & { id: string; createdAt: Date; updatedAt: Date };
|
||||
|
||||
export interface Session {
|
||||
userId: string;
|
||||
expires: Date;
|
||||
sessionToken: string;
|
||||
accessToken: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
// from https://github.com/nextauthjs/next-auth/blob/main/src/lib/errors.js
|
||||
class UnknownError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = "UnknownError";
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
error: {
|
||||
name: this.name,
|
||||
message: this.message,
|
||||
// stack: this.stack
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class CreateUserError extends UnknownError {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = "CreateUserError";
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
|
||||
const basicHeader = (secret) =>
|
||||
"Basic " + Buffer.from(secret + ":", "utf8").toString("base64");
|
||||
|
||||
export const MetamigoAdapter = (config: IAppConfig): Adapter => {
|
||||
if (!config) throw new Error("MetamigoAdapter: config is not defined.");
|
||||
const wreck = Wreck.defaults({
|
||||
headers: {
|
||||
authorization: basicHeader(config.nextAuth.secret),
|
||||
},
|
||||
baseUrl: `${config.frontend.apiUrl}/api/nextauth/`,
|
||||
maxBytes: 1024 * 1024,
|
||||
json: "force",
|
||||
});
|
||||
|
||||
async function getAdapter(_appOptions: AppOptions) {
|
||||
async function createUser(profile: Profile) {
|
||||
try {
|
||||
if (!profile.createdBy) profile = { ...profile, createdBy: "nextauth" };
|
||||
profile.avatar = profile.image;
|
||||
delete profile.image;
|
||||
const { payload } = await wreck.post("createUser", {
|
||||
payload: profile,
|
||||
});
|
||||
return payload;
|
||||
} catch {
|
||||
throw new CreateUserError("CREATE_USER_ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
async function getUser(id: string) {
|
||||
try {
|
||||
const { payload } = await wreck.get(`getUser/${id}`);
|
||||
|
||||
return payload;
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error, 404)) return null;
|
||||
throw new Error("GET_USER_BY_ID_ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
async function getUserByEmail(email: string) {
|
||||
try {
|
||||
const { payload } = await wreck.get(`getUserByEmail/${email}`);
|
||||
return payload;
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error, 404)) return null;
|
||||
throw new Error("GET_USER_BY_EMAIL_ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
async function getUserByProviderAccountId(
|
||||
providerId: string,
|
||||
providerAccountId: string
|
||||
) {
|
||||
try {
|
||||
const { payload } = await wreck.get(
|
||||
`getUserByProviderAccountId/${providerId}/${providerAccountId}`
|
||||
);
|
||||
|
||||
return payload;
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error, 404)) return null;
|
||||
throw new Error("GET_USER_BY_PROVIDER_ACCOUNT_ID");
|
||||
}
|
||||
}
|
||||
|
||||
async function updateUser(user: User) {
|
||||
try {
|
||||
const { payload } = await wreck.put("updateUser", {
|
||||
payload: user,
|
||||
});
|
||||
|
||||
return payload;
|
||||
} catch {
|
||||
throw new Error("UPDATE_USER");
|
||||
}
|
||||
}
|
||||
|
||||
async function linkAccount(
|
||||
userId: string,
|
||||
providerId: string,
|
||||
providerType: string,
|
||||
providerAccountId: string,
|
||||
refreshToken: string,
|
||||
accessToken: string,
|
||||
accessTokenExpires: number
|
||||
) {
|
||||
try {
|
||||
const payload = {
|
||||
userId,
|
||||
providerId,
|
||||
providerType,
|
||||
providerAccountId: `${providerAccountId}`, // must be a string
|
||||
refreshToken,
|
||||
accessToken,
|
||||
accessTokenExpires,
|
||||
};
|
||||
await wreck.put("linkAccount", {
|
||||
payload,
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error("LINK_ACCOUNT_ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
async function createSession(user: User) {
|
||||
try {
|
||||
const { payload } = await wreck.post("createSession", {
|
||||
payload: user,
|
||||
});
|
||||
|
||||
return payload;
|
||||
} catch {
|
||||
throw new Error("CREATE_SESSION_ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
async function getSession(sessionToken: string) {
|
||||
try {
|
||||
const { payload } = await wreck.get(`getSession/${sessionToken}`);
|
||||
return payload;
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error, 404)) return null;
|
||||
throw new Error("GET_SESSION_ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
async function updateSession(session: Session, force: boolean) {
|
||||
try {
|
||||
const payload = {
|
||||
...session,
|
||||
expires: new Date(session.expires).getTime(),
|
||||
};
|
||||
const { payload: result } = await wreck.put(
|
||||
`updateSession?force=${Boolean(force)}`,
|
||||
{
|
||||
payload,
|
||||
}
|
||||
);
|
||||
return result;
|
||||
} catch {
|
||||
throw new Error("UPDATE_SESSION_ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteSession(sessionToken: string) {
|
||||
try {
|
||||
await wreck.delete(`deleteSession/${sessionToken}`);
|
||||
} catch {
|
||||
throw new Error("DELETE_SESSION_ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve({
|
||||
createUser,
|
||||
getUser,
|
||||
getUserByEmail,
|
||||
getUserByProviderAccountId,
|
||||
updateUser,
|
||||
// deleteUser,
|
||||
linkAccount,
|
||||
// unlinkAccount,
|
||||
createSession,
|
||||
getSession,
|
||||
updateSession,
|
||||
deleteSession,
|
||||
// @ts-expect-error: Type error
|
||||
} as AdapterInstance<Profile, User, Session, unknown>);
|
||||
}
|
||||
|
||||
return {
|
||||
// @ts-expect-error: non-existent property
|
||||
getAdapter,
|
||||
};
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue