mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-08-05 03:57:03 -04:00
124 lines
4.2 KiB
TypeScript
124 lines
4.2 KiB
TypeScript
import { defineNuxtPlugin, useCookie, useRuntimeConfig } from 'nuxt/app';
|
|
import type { Pinia } from 'pinia';
|
|
|
|
import useConfig from '../composables/useConfig.ts';
|
|
import { longtimeCookieSetting } from '../src/cookieSettings.ts';
|
|
import { isGrantedForUser, parseUserJwt } from '../src/helpers.ts';
|
|
import type { Account, User } from '../src/user.ts';
|
|
import { useMainStore } from '../store/index.ts';
|
|
|
|
import type { PermissionArea } from '~/src/helpers.ts';
|
|
|
|
declare module '#app' {
|
|
interface NuxtApp {
|
|
$user(): User | null;
|
|
$isGranted(area?: string, locale?: string | null): boolean;
|
|
$accounts(): Promise<void>;
|
|
$setToken(token: string | null): Promise<void>;
|
|
$removeToken(username?: string | null): Promise<void>;
|
|
}
|
|
}
|
|
|
|
declare module 'vue' {
|
|
interface ComponentCustomProperties {
|
|
$user(): User | null;
|
|
$isGranted(area?: string, locale?: string | null): boolean;
|
|
$accounts(): Promise<void>;
|
|
$setToken(token: string | null): Promise<void>;
|
|
$removeToken(username?: string | null): Promise<void>;
|
|
}
|
|
}
|
|
|
|
export default defineNuxtPlugin(async (nuxtApp) => {
|
|
const runtimeConfig = useRuntimeConfig();
|
|
const config = useConfig();
|
|
const store = useMainStore(nuxtApp.$pinia as Pinia);
|
|
|
|
const tokenCookie = useCookie('token', longtimeCookieSetting);
|
|
if (tokenCookie.value) {
|
|
await store.setToken(tokenCookie.value);
|
|
if (!store.token) {
|
|
tokenCookie.value = null;
|
|
}
|
|
}
|
|
|
|
const user = () => store.user;
|
|
const isGranted = (area: PermissionArea = '', locale = null): boolean => {
|
|
return !!store.user &&
|
|
!!store.user.authenticated &&
|
|
isGrantedForUser(store.user, locale || config.locale, area)
|
|
;
|
|
};
|
|
|
|
const getAccounts = async (fallback: string | null = null): Promise<Record<string, Account>> => {
|
|
const tokens = (window.localStorage.getItem('account-tokens') || fallback || '').split('|').filter((x) => !!x);
|
|
const accounts: Record<string, Account> = {};
|
|
for (const token of tokens) {
|
|
const account = await parseUserJwt(token, runtimeConfig.public.publicKey, config.locale);
|
|
if (account !== null && account.username && account.authenticated) {
|
|
accounts[account.username] = { token, account };
|
|
}
|
|
}
|
|
return accounts;
|
|
};
|
|
const saveAccounts = (accounts: Record<string, Account>): void => {
|
|
store.setAccounts(accounts);
|
|
window.localStorage.setItem('account-tokens', Object.values(accounts).map((x) => x.token)
|
|
.join('|'));
|
|
};
|
|
|
|
const accounts = async (): Promise<void> => {
|
|
saveAccounts(await getAccounts(store.token));
|
|
};
|
|
const setToken = async (token: string | null): Promise<void> => {
|
|
const accounts = await getAccounts();
|
|
|
|
const usernameBefore = store.user?.username;
|
|
|
|
tokenCookie.value = token;
|
|
await store.setToken(token);
|
|
if (store.user !== null && store.token !== null) {
|
|
if (store.user.username && store.user.authenticated) {
|
|
accounts[store.user.username] = { token: store.token, account: store.user };
|
|
}
|
|
} else {
|
|
tokenCookie.value = null;
|
|
}
|
|
saveAccounts(accounts);
|
|
|
|
const usernameAfter = store.user?.username;
|
|
|
|
if (usernameBefore !== usernameAfter) {
|
|
const bc = new BroadcastChannel('account_switch');
|
|
bc.postMessage(usernameAfter);
|
|
bc.close();
|
|
}
|
|
};
|
|
const removeToken = async (username: string | null = null): Promise<void> => {
|
|
const accounts = await getAccounts();
|
|
|
|
if (store.user) {
|
|
delete accounts[username || store.user.username];
|
|
}
|
|
if (!username) {
|
|
if (Object.keys(accounts).length === 0) {
|
|
await store.setToken(null);
|
|
tokenCookie.value = null;
|
|
} else {
|
|
await store.setToken(Object.values(accounts)[0].token);
|
|
tokenCookie.value = store.token;
|
|
}
|
|
}
|
|
saveAccounts(accounts);
|
|
};
|
|
return {
|
|
provide: {
|
|
user,
|
|
isGranted,
|
|
accounts,
|
|
setToken,
|
|
removeToken,
|
|
},
|
|
};
|
|
});
|