From 4f8f78157afd18a6493bc92ee4632f76ef4ad429 Mon Sep 17 00:00:00 2001 From: Alican Erdurmaz Date: Thu, 30 May 2024 12:08:26 +0300 Subject: [PATCH 1/3] fix(nextjs-appwrite): auth flow --- .../plugins/data-provider-appwrite/extend.js | 10 ++--- .../data-provider-appwrite/package.json | 20 ++++----- ...th-provider.ts => auth-provider.client.ts} | 43 +++++++++---------- .../auth-provider/auth-provider.server.ts | 26 +++++------ .../src/providers/auth-provider/index.ts | 2 +- .../src/providers/data-provider/index.ts | 34 ++------------- .../src/utils/appwrite/client.ts | 17 ++++++++ .../src/utils/appwrite/server.ts | 20 +++++++++ .../src/{utility => utils}/constants.ts | 2 +- .../src/{utility => utils}/normalize.ts | 0 10 files changed, 92 insertions(+), 82 deletions(-) rename refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/{auth-provider.ts => auth-provider.client.ts} (68%) create mode 100644 refine-nextjs/plugins/data-provider-appwrite/src/utils/appwrite/client.ts create mode 100644 refine-nextjs/plugins/data-provider-appwrite/src/utils/appwrite/server.ts rename refine-nextjs/plugins/data-provider-appwrite/src/{utility => utils}/constants.ts (68%) rename refine-nextjs/plugins/data-provider-appwrite/src/{utility => utils}/normalize.ts (100%) diff --git a/refine-nextjs/plugins/data-provider-appwrite/extend.js b/refine-nextjs/plugins/data-provider-appwrite/extend.js index 6f53d905..ec6964d9 100644 --- a/refine-nextjs/plugins/data-provider-appwrite/extend.js +++ b/refine-nextjs/plugins/data-provider-appwrite/extend.js @@ -2,13 +2,13 @@ const base = { _app: { import: [], localImport: [ - 'import { authProvider } from "@providers/auth-provider";', - 'import { dataProvider, liveProvider } from "@providers/data-provider";', + 'import { authProviderClient } from "@providers/auth-provider";', + 'import { appwriteDataProvider, appwriteLiveProvider } from "@providers/data-provider";', ], refineProps: [ - `dataProvider={dataProvider}`, - `liveProvider={liveProvider}`, - `authProvider={authProvider}`, + "dataProvider={appwriteDataProvider}", + "liveProvider={appwriteLiveProvider}", + "authProvider={authProviderClient}", ], refineOptions: [`liveMode: "auto",`], refineAntdImports: [], diff --git a/refine-nextjs/plugins/data-provider-appwrite/package.json b/refine-nextjs/plugins/data-provider-appwrite/package.json index 0811c763..c4d6761f 100644 --- a/refine-nextjs/plugins/data-provider-appwrite/package.json +++ b/refine-nextjs/plugins/data-provider-appwrite/package.json @@ -1,12 +1,12 @@ { - "dependencies": { - "@refinedev/appwrite": "^6.4.6", - "uuid": "^9.0.0", - "js-cookie": "^3.0.5" - }, - "devDependencies": { - "@types/uuid": "^9.0.2", - "@types/js-cookie": "^3.0.6" - } + "dependencies": { + "@refinedev/appwrite": "^6.4.6", + "uuid": "^9.0.0", + "js-cookie": "^3.0.5", + "node-appwrite": "^13.0.0" + }, + "devDependencies": { + "@types/uuid": "^9.0.2", + "@types/js-cookie": "^3.0.6" + } } - diff --git a/refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/auth-provider.ts b/refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/auth-provider.client.ts similarity index 68% rename from refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/auth-provider.ts rename to refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/auth-provider.client.ts index c443bc61..022b6468 100644 --- a/refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/auth-provider.ts +++ b/refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/auth-provider.client.ts @@ -1,20 +1,24 @@ "use client"; -import { account, appwriteClient } from "@providers/data-provider"; import { AppwriteException } from "@refinedev/appwrite"; -import { AuthBindings } from "@refinedev/core"; -import { APPWRITE_TOKEN_KEY } from "@utility/constants"; +import { AuthProvider } from "@refinedev/core"; +import { appwriteAccount, appwriteClient } from "@utils/appwrite/client"; +import { APPWRITE_JWT_KEY } from "@utils/constants"; import Cookies from "js-cookie"; import { v4 as uuidv4 } from "uuid"; -export const authProvider: AuthBindings = { +export const authProviderClient: AuthProvider = { login: async ({ email, password }) => { try { - await account.createEmailSession(email, password); - const { jwt } = await account.createJWT(); + Cookies.remove(APPWRITE_JWT_KEY, { path: "/" }); + appwriteClient.setJWT(""); + + await appwriteAccount.createEmailSession(email, password); + const { jwt } = await appwriteAccount.createJWT(); + appwriteClient.setJWT(jwt); if (jwt) { - Cookies.set(APPWRITE_TOKEN_KEY, jwt, { + Cookies.set(APPWRITE_JWT_KEY, jwt, { expires: 30, // 30 days path: "/", }); @@ -37,14 +41,10 @@ export const authProvider: AuthBindings = { }, logout: async () => { try { - await account.deleteSession("current"); - } catch (error: any) { - return { - success: false, - error, - }; - } - Cookies.remove(APPWRITE_TOKEN_KEY, { path: "/" }); + await appwriteAccount.deleteSessions(); + } catch (error) {} + + Cookies.remove(APPWRITE_JWT_KEY, { path: "/" }); appwriteClient.setJWT(""); return { success: true, @@ -53,7 +53,7 @@ export const authProvider: AuthBindings = { }, register: async ({ email, password }) => { try { - await account.create(uuidv4(), email, password); + await appwriteAccount.create(uuidv4(), email, password); return { success: true, redirectTo: "/login", @@ -69,18 +69,17 @@ export const authProvider: AuthBindings = { }; } }, - onError: async (error) => { - console.error(error); - return { error }; + onError: async (error: AppwriteException) => { + return { logout: true, redirectTo: "/login", error }; }, check: async () => { - const appwriteJWT = Cookies.get(APPWRITE_TOKEN_KEY); + const appwriteJWT = Cookies.get(APPWRITE_JWT_KEY); if (appwriteJWT) { appwriteClient.setJWT(appwriteJWT); } try { - const session = await account.get(); + const session = await appwriteAccount.get(); if (session) { return { @@ -108,7 +107,7 @@ export const authProvider: AuthBindings = { }, getPermissions: async () => null, getIdentity: async () => { - const user = await account.get(); + const user = await appwriteAccount.get(); if (user) { return user; diff --git a/refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/auth-provider.server.ts b/refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/auth-provider.server.ts index b786f6dc..16ef466b 100644 --- a/refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/auth-provider.server.ts +++ b/refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/auth-provider.server.ts @@ -1,22 +1,22 @@ -import { AuthBindings } from "@refinedev/core"; -import { APPWRITE_TOKEN_KEY } from "@utility/constants"; -import { cookies } from "next/headers"; +import { AuthProvider } from "@refinedev/core"; +import { getSessionClient } from "@utils/appwrite/server"; -export const authProviderServer: Pick = { +export const authProviderServer: Pick = { check: async () => { - const cookieStore = cookies(); - const auth = cookieStore.get(APPWRITE_TOKEN_KEY); + try { + const client = await getSessionClient(); + await client.account.get(); - if (auth) { return { authenticated: true, }; + } catch (error: any) { + return { + authenticated: false, + logout: true, + redirectTo: "/login", + error, + }; } - - return { - authenticated: false, - logout: true, - redirectTo: "/login", - }; }, }; diff --git a/refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/index.ts b/refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/index.ts index b7f6d9fe..36ccb9da 100644 --- a/refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/index.ts +++ b/refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/index.ts @@ -1,2 +1,2 @@ -export * from './auth-provider' +export * from './auth-provider.client' export * from './auth-provider.server' diff --git a/refine-nextjs/plugins/data-provider-appwrite/src/providers/data-provider/index.ts b/refine-nextjs/plugins/data-provider-appwrite/src/providers/data-provider/index.ts index dcfec38d..7d9aaf09 100644 --- a/refine-nextjs/plugins/data-provider-appwrite/src/providers/data-provider/index.ts +++ b/refine-nextjs/plugins/data-provider-appwrite/src/providers/data-provider/index.ts @@ -1,38 +1,12 @@ "use client"; -import { - Account, - Appwrite, - dataProvider as appwriteDataProvider, - liveProvider as appwriteLiveProvider, - Storage, -} from "@refinedev/appwrite"; -import { - APPWRITE_PROJECT, - APPWRITE_TOKEN_KEY, - APPWRITE_URL, -} from "@utility/constants"; -import Cookies from "js-cookie"; +import { dataProvider, liveProvider } from "@refinedev/appwrite"; +import { appwriteClient } from "@utils/appwrite/client"; -const appwriteClient = new Appwrite(); - -appwriteClient.setEndpoint(APPWRITE_URL).setProject(APPWRITE_PROJECT); - -// for client side authentication -const appwriteJWT = Cookies.get(APPWRITE_TOKEN_KEY); -if (appwriteJWT) { - appwriteClient.setJWT(appwriteJWT); -} - -const account = new Account(appwriteClient); -const storage = new Storage(appwriteClient); - -export { appwriteClient, account, storage }; - -export const dataProvider = appwriteDataProvider(appwriteClient, { +export const appwriteDataProvider = dataProvider(appwriteClient, { databaseId: "database", }); -export const liveProvider = appwriteLiveProvider(appwriteClient, { +export const appwriteLiveProvider = liveProvider(appwriteClient, { databaseId: "database", }); diff --git a/refine-nextjs/plugins/data-provider-appwrite/src/utils/appwrite/client.ts b/refine-nextjs/plugins/data-provider-appwrite/src/utils/appwrite/client.ts new file mode 100644 index 00000000..72fce887 --- /dev/null +++ b/refine-nextjs/plugins/data-provider-appwrite/src/utils/appwrite/client.ts @@ -0,0 +1,17 @@ +'use client' + +import { Account, Appwrite, Storage } from '@refinedev/appwrite' +import { APPWRITE_JWT_KEY, APPWRITE_PROJECT, APPWRITE_URL } from '@utils/constants' +import Cookies from 'js-cookie' + +export const appwriteClient = new Appwrite() + +const appwriteJWT = Cookies.get(APPWRITE_JWT_KEY) +if (appwriteJWT) { + appwriteClient.setJWT(appwriteJWT) +} + +appwriteClient.setEndpoint(APPWRITE_URL).setProject(APPWRITE_PROJECT) + +export const appwriteAccount = new Account(appwriteClient) +export const appwriteStorage = new Storage(appwriteClient) diff --git a/refine-nextjs/plugins/data-provider-appwrite/src/utils/appwrite/server.ts b/refine-nextjs/plugins/data-provider-appwrite/src/utils/appwrite/server.ts new file mode 100644 index 00000000..ddc20593 --- /dev/null +++ b/refine-nextjs/plugins/data-provider-appwrite/src/utils/appwrite/server.ts @@ -0,0 +1,20 @@ +import { Client, Account } from 'node-appwrite' +import { cookies } from 'next/headers' +import { APPWRITE_JWT_KEY, APPWRITE_PROJECT, APPWRITE_URL } from '@utils/constants' + +export const getSessionClient = async () => { + const client = new Client().setEndpoint(APPWRITE_URL).setProject(APPWRITE_PROJECT) + + const session = cookies().get(APPWRITE_JWT_KEY) + if (!session || !session.value) { + throw new Error('No session') + } + + client.setJWT(session.value) + + return { + get account() { + return new Account(client) + }, + } +} diff --git a/refine-nextjs/plugins/data-provider-appwrite/src/utility/constants.ts b/refine-nextjs/plugins/data-provider-appwrite/src/utils/constants.ts similarity index 68% rename from refine-nextjs/plugins/data-provider-appwrite/src/utility/constants.ts rename to refine-nextjs/plugins/data-provider-appwrite/src/utils/constants.ts index 3046b430..8be31586 100644 --- a/refine-nextjs/plugins/data-provider-appwrite/src/utility/constants.ts +++ b/refine-nextjs/plugins/data-provider-appwrite/src/utils/constants.ts @@ -1,3 +1,3 @@ export const APPWRITE_URL = "https://refine.appwrite.org/v1"; export const APPWRITE_PROJECT = "61c4368b4e349"; -export const APPWRITE_TOKEN_KEY = "appwrite-jwt"; +export const APPWRITE_JWT_KEY = "appwrite-jwt"; diff --git a/refine-nextjs/plugins/data-provider-appwrite/src/utility/normalize.ts b/refine-nextjs/plugins/data-provider-appwrite/src/utils/normalize.ts similarity index 100% rename from refine-nextjs/plugins/data-provider-appwrite/src/utility/normalize.ts rename to refine-nextjs/plugins/data-provider-appwrite/src/utils/normalize.ts From 4c36b0e150d5f77d7686b1f555d94728eb9aa2e3 Mon Sep 17 00:00:00 2001 From: Alican Erdurmaz Date: Thu, 30 May 2024 12:13:46 +0300 Subject: [PATCH 2/3] fix(nextjs-appwrite): ignore file name --- refine-nextjs/prompt.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/refine-nextjs/prompt.js b/refine-nextjs/prompt.js index 106edeed..bc19573c 100644 --- a/refine-nextjs/prompt.js +++ b/refine-nextjs/prompt.js @@ -186,7 +186,7 @@ module.exports = { when: function (answers) { return answers["ui-framework"] !== "antd"; }, - pattern: ["src/utility/normalize.ts"], + pattern: ["src/utils/normalize.ts"], }, { plugin: ["_base"], From 23dd49af782948b11e1edd3211f8875e2b850c38 Mon Sep 17 00:00:00 2001 From: Alican Erdurmaz Date: Thu, 30 May 2024 13:23:47 +0300 Subject: [PATCH 3/3] fix(nextjs-appwrite): onError --- .../src/providers/auth-provider/auth-provider.client.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/auth-provider.client.ts b/refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/auth-provider.client.ts index 022b6468..375a65f7 100644 --- a/refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/auth-provider.client.ts +++ b/refine-nextjs/plugins/data-provider-appwrite/src/providers/auth-provider/auth-provider.client.ts @@ -70,7 +70,10 @@ export const authProviderClient: AuthProvider = { } }, onError: async (error: AppwriteException) => { - return { logout: true, redirectTo: "/login", error }; + if (error.code === 401) { + return { logout: true, redirectTo: "/login", error }; + } + return { error }; }, check: async () => { const appwriteJWT = Cookies.get(APPWRITE_JWT_KEY);