diff options
Diffstat (limited to 'front-end/src/store')
-rw-r--r-- | front-end/src/store/bookmarks.ts | 1 | ||||
-rw-r--r-- | front-end/src/store/index.ts | 13 | ||||
-rw-r--r-- | front-end/src/store/registation.ts | 110 |
3 files changed, 121 insertions, 3 deletions
diff --git a/front-end/src/store/bookmarks.ts b/front-end/src/store/bookmarks.ts index 76cc5b9..2af8344 100644 --- a/front-end/src/store/bookmarks.ts +++ b/front-end/src/store/bookmarks.ts @@ -33,6 +33,7 @@ export interface Bookmark{ export interface BatchUploadResult{ readonly invalid: BookmarkError[] + readonly message?: string } export interface BookmarkError{ diff --git a/front-end/src/store/index.ts b/front-end/src/store/index.ts index bcd79ad..09c5a2d 100644 --- a/front-end/src/store/index.ts +++ b/front-end/src/store/index.ts @@ -15,7 +15,7 @@ import { useSession, useAutoHeartbeat } from "@vnuge/vnlib.browser"; import { toRefs, set, watchDebounced, useLocalStorage } from "@vueuse/core"; -import { noop, toSafeInteger, toString, defaults } from "lodash-es"; +import { toSafeInteger, toString, defaults } from "lodash-es"; import { defineStore } from "pinia"; import { computed, shallowRef, watch } from "vue"; @@ -53,7 +53,8 @@ export enum TabId{ Bookmarks, Profile, Settings, - Login + Login, + Register } /** @@ -80,7 +81,13 @@ export const useStore = defineStore('main', () => { }) //If not logged in, redirect to login tab - watch(loggedIn, (loggedIn) => loggedIn ? noop() : set(activeTab, TabId.Login), { immediate: true }) + watch(loggedIn, (li) =>{ + if (li || activeTab.value == TabId.Register){ + return; + } + + set(activeTab, TabId.Login); + }, { immediate: true }) //Setup heartbeat for 5 minutes useAutoHeartbeat(shallowRef(5 * 60 * 1000), autoHeartbeat) diff --git a/front-end/src/store/registation.ts b/front-end/src/store/registation.ts new file mode 100644 index 0000000..b07e3e2 --- /dev/null +++ b/front-end/src/store/registation.ts @@ -0,0 +1,110 @@ +// Copyright (C) 2024 Vaughn Nugent +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +import 'pinia' +import { MaybeRef, shallowRef, watch } from 'vue'; +import { WebMessage, useAxios } from '@vnuge/vnlib.browser'; +import { get } from '@vueuse/core'; +import { PiniaPluginContext, PiniaPlugin, storeToRefs } from 'pinia' +import { defer } from 'lodash-es'; +import { TabId } from '.'; + +export interface SignupToken { + readonly link: string +} + +export interface RegistationStatus{ + readonly setup_mode: boolean + readonly enabled: boolean + readonly can_invite: boolean + readonly link_expiration: number +} + +export interface UserRegistationApi { + createSignupLink(username: string, canAddUsers: boolean): Promise<SignupToken> + getStatus(): Promise<RegistationStatus> + registerAdmin(username: string, password: string): Promise<WebMessage<string>> + completeRegistation(token: string, password: string): Promise<WebMessage<string>> +} + +declare module 'pinia' { + export interface PiniaCustomProperties { + registation:{ + api: UserRegistationApi + status: RegistationStatus | undefined + } + } +} + + +const useRegApi = (endpoint: MaybeRef<string>): UserRegistationApi => { + + const axios = useAxios(null); + + const createSignupLink = async (username: string, hasAddPerms: boolean): Promise<SignupToken> => { + const { data } = await axios.put<WebMessage<string>>(get(endpoint), { + username, + can_add_users:hasAddPerms + }) + + const token = data.getResultOrThrow(); + + return { link: `${window.location.origin}?tab=${TabId.Register}&token=${token}` } + } + + const getStatus = async (): Promise<RegistationStatus> => { + const { data } = await axios.get<WebMessage<RegistationStatus>>(get(endpoint)) + return data.getResultOrThrow(); + } + + const completeRegistation = async (token: string, password: string): Promise<WebMessage<string>> => { + const { data } = await axios.post<WebMessage<string>>(get(endpoint), { token, password }) + return data; + } + + const registerAdmin = async (username: string, password: string): Promise<WebMessage<string>> => { + const { data } = await axios.post<WebMessage<string>>(get(endpoint), { admin_username:username, password }) + return data; + } + + return { + createSignupLink, + getStatus, + completeRegistation, + registerAdmin + } +} + +export const registationPlugin = (regEndpoint: MaybeRef<string>): PiniaPlugin => { + + return ({ store }: PiniaPluginContext): any => { + + const { loggedIn } = storeToRefs(store) + + const regApi = useRegApi(regEndpoint) + const status = shallowRef<RegistationStatus | undefined>() + + const getStatus = async () => status.value = await regApi.getStatus() + + watch(loggedIn, () => defer(getStatus), { immediate: true }) + + return{ + registation: { + api: regApi, + status, + } + } + } +}
\ No newline at end of file |