import isEmpty from 'lodash/isEmpty'; import { AuthProvider, OnErrorResponse } from "@refinedev/core"; import { IUser } from "../interfaces"; const API_URL = "/api/v1"; const LOCAL_STORAGE_USER_KEY = "rpk-gui-current-user"; const GOOGLE_SCOPES = { "scopes": "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email" }; const DISCORD_SCOPES = { "scopes": "identify email" } const DEFAULT_LOGIN_REDIRECT = "/hub" const authProvider: AuthProvider = { login: async ({ providerName, email, password }) => { const to_param = findGetParameter("to"); const redirect = to_param === null ? getLoginRedirect() : to_param if (providerName) { let scope = {}; if (providerName === "google") { scope = GOOGLE_SCOPES; } else if (providerName === "discord") { scope = DISCORD_SCOPES; } const params = new URLSearchParams(scope); const url = `${API_URL}/hub/auth/${providerName}/authorize?${params.toString()}`; const response = await fetch(url, { method: "GET", },); const body = await response.json(); localStorage.setItem("redirect_after_login", redirect); window.location.href = body.authorization_url; return { success: true, redirectTo: "" }; } else if (email !== undefined && password !== undefined) { const params = new URLSearchParams({"grant_type": "password", "username": email, "password": password}); const response = await fetch( `${API_URL}/hub/auth/login`, { method: "POST", body: params.toString(), headers: { "Content-Type": "application/x-www-form-urlencoded", }, }, ); if (response.status >= 200 && response.status < 300) { const response = await fetch(`${API_URL}/hub/users/me`); const user = await response.json(); store_user(user); return { success: true, redirectTo: redirect, }; } } return { success: false }; }, logout: async () => { const response = await fetch(`${API_URL}/hub/auth/logout`, { method: "POST" }); if (response.status == 204 || response.status == 401) { forget_user(); return { success: true }; } return { success: false }; }, check: async () => { const user = get_user(); if (user == null || isEmpty(user)) { const user_data = await get_me(); if (user_data) { store_user(user_data) return { authenticated: true } } return { authenticated: false, logout: true } } return { authenticated: true }; }, getIdentity: async (): Promise => { const user = get_user(); if (user !== null && !isEmpty(user)) { return user; } const user_data = get_me() store_user(user_data) return user_data; }, register: async (params) => { const response = await fetch(`${API_URL}/hub/register`, { method: "POST", body: JSON.stringify(params), headers: { "Content-Type": "application/json", }, }); if (response.status == 201) { return { success: true, redirectTo: "/", }; } return { success: false, error: { message: "Register failed", name: "Invalid email or password", }, }; }, forgotPassword: async (params) => { const response = await fetch(`${API_URL}/hub/users/forgot-password`, { method: "POST", body: JSON.stringify(params), headers: { "Content-Type": "application/json", }, }); if (response.status == 202) { return { success: true, redirectTo: "/", }; } return { success: false, }; }, updatePassword: async (params) => { if (params.token !== undefined) { const response = await fetch(`${API_URL}/hub/users/reset-password`, { method: "POST", body: JSON.stringify({ password: params.password, token: params.token, }), headers: { "Content-Type": "application/json", }, }); if (response.status == 200) { return { success: true, redirectTo: "/", }; } } return { success: false, }; }, getPermissions: async () => { throw new Error("Not implemented"); }, onError: async (error) => { if (error?.status === 401) { forget_user(); return { error: { message: "Authentication required" }, logout: true, } as OnErrorResponse; } else if (error?.status === 403) { return { error: { message: "Insufficient credentials" }, } as OnErrorResponse; } return { error: { message: "Unexpected authentication error" }, } as OnErrorResponse; }, }; async function get_me() { const response = await fetch(`${API_URL}/hub/users/me`); if (response.status < 200 || response.status > 299) { return null; } const user_data = await response.json(); return user_data } function store_user(user: any) { localStorage.setItem(LOCAL_STORAGE_USER_KEY, JSON.stringify(user)); } function get_user() { const user_string = localStorage.getItem(LOCAL_STORAGE_USER_KEY) if (user_string == null) { return null } return JSON.parse(user_string); } function forget_user() { localStorage.removeItem(LOCAL_STORAGE_USER_KEY); } export function empty_user() { store_user({}) } function findGetParameter(parameterName: string) { let result = null, tmp = []; location.search.substring(1).split("&") .forEach(function (item) { tmp = item.split("="); if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]); }); return result; } function getLoginRedirect() { if (location.pathname == "/login") { return DEFAULT_LOGIN_REDIRECT } return location.pathname + location.search; } export default authProvider;