aboutsummaryrefslogtreecommitdiff
path: root/front-end/src/store
diff options
context:
space:
mode:
Diffstat (limited to 'front-end/src/store')
-rw-r--r--front-end/src/store/bookmarks.ts1
-rw-r--r--front-end/src/store/index.ts13
-rw-r--r--front-end/src/store/registation.ts110
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