93 lines
2.3 KiB
TypeScript
93 lines
2.3 KiB
TypeScript
import { Capacitor } from "@capacitor/core";
|
|
import { Preferences } from "@capacitor/preferences";
|
|
import type { User } from "~/types";
|
|
|
|
export function useAuth() {
|
|
const user = useState<User | null>("auth-user", () => null);
|
|
const token = useState<string | null>("auth-token", () => null);
|
|
const loading = useState<boolean>("auth-loading", () => true);
|
|
|
|
const isNativeApp = () => process.client && Capacitor.isNativePlatform();
|
|
const webTokenStorageKey = "auth-token";
|
|
|
|
const persistToken = async (nextToken: string | null) => {
|
|
if (!process.client) {
|
|
return;
|
|
}
|
|
|
|
if (isNativeApp()) {
|
|
if (nextToken) {
|
|
await Preferences.set({ key: webTokenStorageKey, value: nextToken });
|
|
return;
|
|
}
|
|
|
|
await Preferences.remove({ key: webTokenStorageKey });
|
|
return;
|
|
}
|
|
|
|
if (nextToken) {
|
|
window.localStorage.setItem(webTokenStorageKey, nextToken);
|
|
return;
|
|
}
|
|
|
|
window.localStorage.removeItem(webTokenStorageKey);
|
|
};
|
|
|
|
const restoreToken = async () => {
|
|
if (!process.client || token.value) {
|
|
return;
|
|
}
|
|
|
|
if (isNativeApp()) {
|
|
const storedToken = await Preferences.get({ key: webTokenStorageKey });
|
|
token.value = storedToken.value;
|
|
return;
|
|
}
|
|
|
|
token.value = window.localStorage.getItem(webTokenStorageKey);
|
|
};
|
|
|
|
const setSession = async (nextToken: string | null, nextUser: User | null) => {
|
|
token.value = nextToken;
|
|
user.value = nextUser;
|
|
await persistToken(nextToken);
|
|
};
|
|
|
|
const refreshMe = async () => {
|
|
await restoreToken();
|
|
|
|
try {
|
|
const me = await useApi<User>("/auth/me");
|
|
user.value = me;
|
|
} catch {
|
|
await setSession(null, null);
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
};
|
|
|
|
const login = async (nextToken: string | null, nextUser: User) => {
|
|
loading.value = false;
|
|
await setSession(nextToken, nextUser);
|
|
};
|
|
|
|
const logout = async () => {
|
|
const { deactivateCurrentPushSubscription, syncServiceWorkerContext } = usePush();
|
|
|
|
await deactivateCurrentPushSubscription().catch(() => undefined);
|
|
await useApi("/auth/logout", { method: "POST" }).catch(() => undefined);
|
|
await setSession(null, null);
|
|
await syncServiceWorkerContext().catch(() => undefined);
|
|
await navigateTo("/login");
|
|
};
|
|
|
|
return {
|
|
user,
|
|
token,
|
|
loading,
|
|
login,
|
|
logout,
|
|
refreshMe
|
|
};
|
|
}
|