refactor: major refactor of the providers and resources to be more dynamic and flexible
This commit is contained in:
parent
2e918e7802
commit
ff5e5dec14
|
@ -0,0 +1,11 @@
|
|||
import type { DataProvider } from "@refinedev/core";
|
||||
import {SdkProvider} from "~/data/sdk-provider.js";
|
||||
|
||||
export const accountProvider: SdkProvider = {
|
||||
getList: () => { throw Error("Not Implemented") },
|
||||
getOne: () => { throw Error("Not Implemented") },
|
||||
update: () => { throw Error("Not Implemented") },
|
||||
create: () => { throw Error("Not Implemented") },
|
||||
deleteOne: () => { throw Error("Not Implemented") },
|
||||
getApiUrl: () => "",
|
||||
}
|
|
@ -31,134 +31,94 @@ export type Identity = {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export class PortalAuthProvider implements RequiredAuthProvider {
|
||||
constructor(apiUrl: string) {
|
||||
this._sdk = Sdk.create(apiUrl);
|
||||
|
||||
const methods: Array<keyof AuthProvider> = [
|
||||
'login',
|
||||
'logout',
|
||||
'check',
|
||||
'onError',
|
||||
'register',
|
||||
'forgotPassword',
|
||||
'updatePassword',
|
||||
'getPermissions',
|
||||
'getIdentity',
|
||||
];
|
||||
|
||||
methods.forEach((method) => {
|
||||
this[method] = this[method]?.bind(this) as any;
|
||||
});
|
||||
}
|
||||
|
||||
private _sdk: Sdk;
|
||||
|
||||
get sdk(): Sdk {
|
||||
return this._sdk;
|
||||
}
|
||||
|
||||
public static create(apiUrl: string): AuthProvider {
|
||||
return new PortalAuthProvider(apiUrl);
|
||||
}
|
||||
|
||||
async login(params: AuthFormRequest): Promise<AuthActionResponse> {
|
||||
const ret = await this._sdk.account().login({
|
||||
email: params.email,
|
||||
password: params.password,
|
||||
})
|
||||
|
||||
let redirectTo: string | undefined;
|
||||
|
||||
if (ret) {
|
||||
redirectTo = params.redirectTo;
|
||||
if (!redirectTo) {
|
||||
redirectTo = ret ? "/dashboard" : "/login";
|
||||
}
|
||||
this._sdk.setAuthToken(this._sdk.account().jwtToken);
|
||||
}
|
||||
|
||||
return {
|
||||
success: ret,
|
||||
redirectTo,
|
||||
};
|
||||
}
|
||||
|
||||
async logout(params: any): Promise<AuthActionResponse> {
|
||||
let ret = await this._sdk.account().logout();
|
||||
return {success: ret, redirectTo: "/login"};
|
||||
}
|
||||
|
||||
async check(params?: any): Promise<CheckResponse> {
|
||||
const ret = await this._sdk.account().ping();
|
||||
|
||||
if(ret){
|
||||
this.maybeSetupAuth();
|
||||
}
|
||||
|
||||
return {authenticated: ret, redirectTo: ret ? undefined : "/login"};
|
||||
}
|
||||
|
||||
async onError(error: any): Promise<OnErrorResponse> {
|
||||
return {logout: true};
|
||||
}
|
||||
|
||||
async register(params: RegisterFormRequest): Promise<AuthActionResponse> {
|
||||
const ret = await this._sdk.account().register({
|
||||
email: params.email,
|
||||
password: params.password,
|
||||
first_name: params.firstName,
|
||||
last_name: params.lastName,
|
||||
});
|
||||
return {success: ret, redirectTo: ret ? "/dashboard" : undefined};
|
||||
}
|
||||
|
||||
async forgotPassword(params: any): Promise<AuthActionResponse> {
|
||||
return {success: true};
|
||||
}
|
||||
|
||||
async updatePassword(params: any): Promise<AuthActionResponse> {
|
||||
return {success: true};
|
||||
}
|
||||
|
||||
async getPermissions(params?: Record<string, any>): Promise<AuthActionResponse> {
|
||||
return {success: true};
|
||||
}
|
||||
|
||||
async getIdentity(params?: Identity): Promise<IdentityResponse> {
|
||||
this.maybeSetupAuth();
|
||||
const ret = await this._sdk.account().info();
|
||||
|
||||
if (!ret) {
|
||||
return {identity: null};
|
||||
}
|
||||
|
||||
const acct = ret as AccountInfoResponse;
|
||||
|
||||
return {
|
||||
id: acct.id,
|
||||
firstName: acct.first_name,
|
||||
lastName: acct.last_name,
|
||||
email: acct.email,
|
||||
};
|
||||
}
|
||||
|
||||
maybeSetupAuth(): void {
|
||||
const jwt = this._sdk.account().jwtToken
|
||||
export const createPortalAuthProvider = (sdk: Sdk): AuthProvider => {
|
||||
const maybeSetupAuth = (): void => {
|
||||
const jwt = sdk.account().jwtToken;
|
||||
if (jwt) {
|
||||
this._sdk.setAuthToken(jwt);
|
||||
sdk.setAuthToken(jwt);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export interface RequiredAuthProvider extends AuthProvider {
|
||||
login: AuthProvider['login'];
|
||||
logout: AuthProvider['logout'];
|
||||
check: AuthProvider['check'];
|
||||
onError: AuthProvider['onError'];
|
||||
register: AuthProvider['register'];
|
||||
forgotPassword: AuthProvider['forgotPassword'];
|
||||
updatePassword: AuthProvider['updatePassword'];
|
||||
getPermissions: AuthProvider['getPermissions'];
|
||||
getIdentity: AuthProvider['getIdentity'];
|
||||
}
|
||||
return {
|
||||
async login(params: AuthFormRequest): Promise<AuthActionResponse> {
|
||||
const ret = await sdk.account().login({
|
||||
email: params.email,
|
||||
password: params.password,
|
||||
});
|
||||
|
||||
let redirectTo: string | undefined;
|
||||
|
||||
if (ret) {
|
||||
redirectTo = params.redirectTo;
|
||||
if (!redirectTo) {
|
||||
redirectTo = ret ? "/dashboard" : "/login";
|
||||
}
|
||||
sdk.setAuthToken(sdk.account().jwtToken);
|
||||
}
|
||||
|
||||
return {
|
||||
success: ret,
|
||||
redirectTo,
|
||||
};
|
||||
},
|
||||
|
||||
async logout(params: any): Promise<AuthActionResponse> {
|
||||
let ret = await sdk.account().logout();
|
||||
return { success: ret, redirectTo: "/login" };
|
||||
},
|
||||
|
||||
async check(params?: any): Promise<CheckResponse> {
|
||||
const ret = await sdk.account().ping();
|
||||
|
||||
if (ret) {
|
||||
maybeSetupAuth();
|
||||
}
|
||||
|
||||
return { authenticated: ret, redirectTo: ret ? undefined : "/login" };
|
||||
},
|
||||
|
||||
async onError(error: any): Promise<OnErrorResponse> {
|
||||
return { logout: true };
|
||||
},
|
||||
|
||||
async register(params: RegisterFormRequest): Promise<AuthActionResponse> {
|
||||
const ret = await sdk.account().register({
|
||||
email: params.email,
|
||||
password: params.password,
|
||||
first_name: params.firstName,
|
||||
last_name: params.lastName,
|
||||
});
|
||||
return { success: ret, redirectTo: ret ? "/dashboard" : undefined };
|
||||
},
|
||||
|
||||
async forgotPassword(params: any): Promise<AuthActionResponse> {
|
||||
return { success: true };
|
||||
},
|
||||
|
||||
async updatePassword(params: any): Promise<AuthActionResponse> {
|
||||
return { success: true };
|
||||
},
|
||||
|
||||
async getPermissions(params?: Record<string, any>): Promise<AuthActionResponse> {
|
||||
return { success: true };
|
||||
},
|
||||
|
||||
async getIdentity(params?: Identity): Promise<IdentityResponse> {
|
||||
maybeSetupAuth();
|
||||
const ret = await sdk.account().info();
|
||||
|
||||
if (!ret) {
|
||||
return { identity: null };
|
||||
}
|
||||
|
||||
const acct = ret as AccountInfoResponse;
|
||||
|
||||
return {
|
||||
id: acct.id,
|
||||
firstName: acct.first_name,
|
||||
lastName: acct.last_name,
|
||||
email: acct.email,
|
||||
};
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import type { DataProvider } from "@refinedev/core";
|
||||
import {SdkProvider} from "~/data/sdk-provider.js";
|
||||
|
||||
export const defaultProvider: DataProvider = {
|
||||
export const fileProvider: SdkProvider = {
|
||||
getList: () => { throw Error("Not Implemented") },
|
||||
getOne: () => { throw Error("Not Implemented") },
|
||||
update: () => { throw Error("Not Implemented") },
|
||||
create: () => { throw Error("Not Implemented") },
|
||||
deleteOne: () => { throw Error("Not Implemented") },
|
||||
getApiUrl: () => "",
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import type {AuthProvider, DataProvider} from "@refinedev/core";
|
||||
import {fileProvider} from "~/data/file-provider.js";
|
||||
import {Sdk} from "@lumeweb/portal-sdk";
|
||||
import {accountProvider} from "~/data/account-provider.js";
|
||||
import type {SdkProvider} from "~/data/sdk-provider.js";
|
||||
import {createPortalAuthProvider} from "~/data/auth-provider.js";
|
||||
|
||||
interface DataProviders {
|
||||
default: SdkProvider;
|
||||
auth: AuthProvider;
|
||||
|
||||
[key: string]: SdkProvider | AuthProvider;
|
||||
}
|
||||
|
||||
let providers: DataProviders;
|
||||
|
||||
export function getProviders(sdk: Sdk) {
|
||||
if (providers) {
|
||||
return providers;
|
||||
}
|
||||
|
||||
accountProvider.sdk = sdk;
|
||||
fileProvider.sdk = sdk;
|
||||
providers = {
|
||||
default: accountProvider,
|
||||
auth: createPortalAuthProvider(sdk),
|
||||
files: fileProvider,
|
||||
};
|
||||
|
||||
return providers;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import type {ResourceProps} from "@refinedev/core";
|
||||
|
||||
const resources: ResourceProps[] = [
|
||||
{
|
||||
name: 'account',
|
||||
meta: {
|
||||
dataProviderName: 'default',
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'file',
|
||||
meta: {
|
||||
dataProviderName: 'files',
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
export default resources;
|
|
@ -0,0 +1,6 @@
|
|||
import {DataProvider} from "@refinedev/core";
|
||||
import {Sdk} from "@lumeweb/portal-sdk";
|
||||
|
||||
export interface SdkProvider extends DataProvider {
|
||||
sdk?: Sdk;
|
||||
}
|
29
app/root.tsx
29
app/root.tsx
|
@ -1,21 +1,16 @@
|
|||
import {
|
||||
Links,
|
||||
Meta,
|
||||
Outlet,
|
||||
Scripts,
|
||||
ScrollRestoration,
|
||||
} from "@remix-run/react";
|
||||
import {Links, Meta, Outlet, Scripts, ScrollRestoration,} from "@remix-run/react";
|
||||
|
||||
import stylesheet from "./tailwind.css?url";
|
||||
import type { LinksFunction } from "@remix-run/node";
|
||||
import type {LinksFunction} from "@remix-run/node";
|
||||
|
||||
// Supports weights 200-800
|
||||
import '@fontsource-variable/manrope';
|
||||
import {Refine} from "@refinedev/core";
|
||||
import {PortalAuthProvider} from "~/data/auth-provider.js";
|
||||
import routerProvider from "@refinedev/remix-router";
|
||||
import { defaultProvider } from "./data/file-provider";
|
||||
import {SdkContextProvider} from "~/components/lib/sdk-context.js";
|
||||
import {getProviders} from "~/data/providers.js";
|
||||
import {Sdk} from "@lumeweb/portal-sdk";
|
||||
import resources from "~/data/resources.js";
|
||||
|
||||
export const links: LinksFunction = () => [
|
||||
{ rel: "stylesheet", href: stylesheet },
|
||||
|
@ -40,19 +35,17 @@ export function Layout({children}: { children: React.ReactNode }) {
|
|||
}
|
||||
|
||||
export default function App() {
|
||||
const auth = PortalAuthProvider.create("https://alpha.pinner.xyz")
|
||||
const sdk = Sdk.create(import.meta.env.VITE_PORTAL_URL)
|
||||
const providers = getProviders(sdk);
|
||||
return (
|
||||
<Refine
|
||||
authProvider={auth}
|
||||
authProvider={providers.auth}
|
||||
routerProvider={routerProvider}
|
||||
dataProvider={defaultProvider}
|
||||
resources={[
|
||||
{ name: 'files' },
|
||||
{ name: 'users' }
|
||||
]}
|
||||
dataProvider={providers.default}
|
||||
resources={resources}
|
||||
options={{disableTelemetry: true}}
|
||||
>
|
||||
<SdkContextProvider sdk={(auth as PortalAuthProvider).sdk}>
|
||||
<SdkContextProvider sdk={sdk}>
|
||||
<Outlet/>
|
||||
</SdkContextProvider>
|
||||
</Refine>
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
/// <reference types="vite/client" />
|
||||
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_PORTAL_API_URL: string
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv
|
||||
}
|
Loading…
Reference in New Issue