UNPKG

appwrite-server-wrapper

Version:

Wrapper library to handle Appwrite methods including server handling using SSR with NextJS v15 (useActionState, useAction,...)

537 lines (536 loc) 15.5 kB
"use server"; import { cookieName, signInPath, databaseId, oauthSuccessPath, oauthFailurePath, verificationPath, usersCollectionId, } from "../appwriteConfig"; import { cookies } from "next/headers"; import { hostExternal, live } from "../host"; import { OAuthProvider } from "../enums"; import { handleApwError } from "../exceptions"; import { ID, Query } from "node-appwrite"; import { getType } from "../collections/typeReader"; import { createSessionClient, createAdminClient } from "../appwriteClients"; let ApwUserType; let UserType; const init = async () => { ApwUserType = await getType({ typeFileName: "user", // without extension typeName: "ApwUserType", }); if (!ApwUserType) { throw new Error("No Type 'ApwUserType' found (service: account)."); } UserType = await getType({ typeFileName: "user", // without extension typeName: "UserType", }); if (!UserType) { throw new Error("No Type 'UserType' found (service: account)."); } }; init(); const addPrefs = async ({ prefs, }) => { try { const { account } = await createSessionClient(); const currentPrefs = await account.getPrefs(); // Ensure prefs is a valid JSON string let newPrefs = {}; newPrefs = JSON.parse(prefs); if (typeof newPrefs !== "object" || Array.isArray(newPrefs)) { throw new Error("Invalid prefs format. Must be a stringified JSON object."); } const updatedPrefs = { ...currentPrefs, ...newPrefs }; const user = await account.updatePrefs(updatedPrefs); return { data: user.prefs, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Update preferences for a user. */ const updatePrefs = async ({ prefs, }) => { try { const { account } = await createSessionClient(); const currentPrefs = await account.getPrefs(); // Ensure prefs is a valid JSON string let newPrefs = {}; newPrefs = JSON.parse(prefs); if (typeof newPrefs !== "object" || Array.isArray(newPrefs)) { throw new Error("Invalid prefs format. Must be a stringified JSON object."); } const updatedPrefs = { ...currentPrefs, ...newPrefs }; const user = await account.updatePrefs(updatedPrefs); return { data: user.prefs, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Creates an account. */ const createAccount = async ({ email, password, name, }) => { try { const { account } = await createAdminClient(); const data = await account.create(ID.unique(), email, password, name); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Creates an anonymous session. */ const createAnonymousSession = async () => { try { const { account } = await createAdminClient(); const data = await account.createAnonymousSession(); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Creates an email-password session. */ const createEmailPasswordSession = async ({ email, password, }) => { try { const { account } = await createAdminClient(); const data = await account.createEmailPasswordSession(email, password); (await cookies()).set(cookieName, data.secret, { httpOnly: true, secure: live, sameSite: "strict", expires: new Date(data.expire), path: "/", }); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Creates a JWT token. */ const createJWT = async () => { try { const { account } = await createSessionClient(); const data = await account.createJWT(); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Creates a Magic URL session. */ const createMagicURLSession = async ({ email, url, userId, phrase, }) => { try { const { account } = await createAdminClient(); const data = await account.createMagicURLToken(userId || ID.unique(), email, url, phrase); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Creates an OAuth2 token. */ const createOAuth2Token = async ({ provider, successPath = oauthSuccessPath, failurePath = oauthFailurePath, scopes = [], }) => { try { const { account } = await createAdminClient(); const data = await account.createOAuth2Token(OAuthProvider[provider], `${hostExternal}/${successPath}`, `${hostExternal}/${failurePath}`, scopes); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Creates a phone verification token. */ const createPhoneVerification = async () => { try { const { account } = await createAdminClient(); const data = await account.createPhoneVerification(); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Sends a password recovery email. */ const createRecovery = async ({ email, url, }) => { try { const { account } = await createAdminClient(); const data = await account.createRecovery(email, url); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Creates a session using user ID and secret. */ const createSession = async ({ userId, secret, }) => { try { const { account } = await createAdminClient(); const data = await account.createSession(userId, secret); (await cookies()).set(cookieName, data.secret, { httpOnly: true, secure: live, sameSite: "strict", expires: new Date(data.expire), path: "/", }); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Creates an email verification token. */ const createVerification = async ({ verificationUrl = `${hostExternal}/${verificationPath}`, }) => { try { const { account } = await createAdminClient(); const data = await account.createVerification(verificationUrl); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; const deletePrefs = async ({ keys, }) => { try { const { account } = await createSessionClient(); const prefs = await account.getPrefs(); // Convert keys to an array if it's a stringified JSON let keysToDelete = []; if (typeof keys === "string") { try { const parsedKeys = JSON.parse(keys); keysToDelete = Array.isArray(parsedKeys) ? parsedKeys : [parsedKeys]; } catch { keysToDelete = [keys]; // Treat as a single key if parsing fails } } else { keysToDelete = keys; } // Filter out the keys that need to be removed const newPrefs = Object.fromEntries(Object.entries(prefs).filter(([key]) => !keysToDelete.includes(key))); // Update user preferences const user = await account.updatePrefs(newPrefs); return { data: user.prefs, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Deletes a session. */ const deleteSession = async ({ sessionId = "current", } = {}) => { try { const { account } = await createSessionClient(); await account.deleteSession(sessionId); return { data: signInPath, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Deletes all sessions for the current user. */ const deleteSessions = async () => { try { const { account } = await createSessionClient(); await account.deleteSessions(); return { data: signInPath, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Retrieves a authenticated and verified native appwrite user. */ const getApwUser = async () => { try { const { account } = await createSessionClient(); const data = await account.get(); if (!data?.$id) { return { data: null, error: null }; } if ((data.emailVerification || data.phoneVerification) && data.status) { return { data, error: null, }; } return { data: null, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Retrieves a authenticated and verified a custom user (from users collection). */ const getUser = async () => { try { const { account } = await createSessionClient(); const { databases } = await createAdminClient(); const data = await account.get(); if (!data?.$id) { return { data: null, error: null }; } const { total, documents } = await databases.listDocuments(databaseId, usersCollectionId, [Query.equal("user_id", data.$id)]); return { data: total === 1 ? documents[0] : null, error: null, }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Retrieves a specific session or the current session. */ const getSession = async ({ sessionId = "current", } = {}) => { try { const { account } = await createSessionClient(); const data = await account.getSession(sessionId); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Lists all sessions for the current user. */ const listSessions = async () => { try { const { account } = await createSessionClient(); const data = await account.listSessions(); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Updates user email. */ const updateEmail = async ({ email, password, }) => { try { const { account } = await createSessionClient(); const data = await account.updateEmail(email, password); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Updates user name. */ const updateName = async ({ name, }) => { try { const { account } = await createSessionClient(); const data = await account.updateName(name); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Updates user password. */ const updatePassword = async ({ password, oldPassword, }) => { try { const { account } = await createSessionClient(); const data = await account.updatePassword(password, oldPassword); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Updates user phone number. */ const updatePhone = async ({ phone, password, }) => { try { const { account } = await createSessionClient(); const data = await account.updatePhone(phone, password); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Confirms phone verification. */ const updatePhoneVerification = async ({ userId, secret, }) => { try { const { account } = await createSessionClient(); const data = await account.updatePhoneVerification(userId, secret); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Updates the password using a recovery token. */ const updateRecovery = async ({ userId, secret, password, }) => { try { const { account } = await createSessionClient(); const data = await account.updateRecovery(userId, secret, password); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Updates a specific session or the current session. */ const updateSession = async ({ sessionId = "current", }) => { try { const { account } = await createSessionClient(); const data = await account.updateSession(sessionId); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Updates user status. */ const updateStatus = async () => { try { const { account } = await createSessionClient(); const data = await account.updateStatus(); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; /* * Updates email verification. */ const updateVerification = async ({ userId, secret, }) => { try { const { account } = await createSessionClient(); const data = await account.updateVerification(userId, secret); return { data, error: null }; } catch (error) { return { data: null, error: await handleApwError({ error }), }; } }; export { addPrefs, createAccount, createAnonymousSession, createEmailPasswordSession, createJWT, createMagicURLSession, createOAuth2Token, createPhoneVerification, createRecovery, createSession, createVerification, deletePrefs, deleteSession, deleteSessions, getApwUser, getSession, getUser, listSessions, updateEmail, updateName, updatePassword, updatePhone, updatePhoneVerification, updatePrefs, updateRecovery, updateSession, updateStatus, updateVerification, };