From bd3a7a25792b837c5f28c7580adf132abc6f35e7 Mon Sep 17 00:00:00 2001 From: vnugent Date: Sun, 25 Feb 2024 01:11:06 -0500 Subject: Squashed commit of the following: commit 069f81fc3c87c437eceff756ddca7a4c1b58044d Author: vnugent Date: Sat Feb 24 22:33:34 2024 -0500 feat: #3 setup mode, admin signup, fixes, and contianerize! commit 97ffede9eb312fca0257afa06969d47a12703f3b Author: vnugent Date: Mon Feb 19 22:26:03 2024 -0500 feat: new account setup and invitation links commit 1c8f59bc0a1b25ce5013b0f1fc7fa73c0de415d6 Author: vnugent Date: Thu Feb 15 16:49:59 2024 -0500 feat: update packages, drag/drop link, and fix some button padding --- front-end/src/store/bookmarks.ts | 1 + front-end/src/store/index.ts | 13 ++++- front-end/src/store/registation.ts | 110 +++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 front-end/src/store/registation.ts (limited to 'front-end/src/store') 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 . + +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 + getStatus(): Promise + registerAdmin(username: string, password: string): Promise> + completeRegistation(token: string, password: string): Promise> +} + +declare module 'pinia' { + export interface PiniaCustomProperties { + registation:{ + api: UserRegistationApi + status: RegistationStatus | undefined + } + } +} + + +const useRegApi = (endpoint: MaybeRef): UserRegistationApi => { + + const axios = useAxios(null); + + const createSignupLink = async (username: string, hasAddPerms: boolean): Promise => { + const { data } = await axios.put>(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 => { + const { data } = await axios.get>(get(endpoint)) + return data.getResultOrThrow(); + } + + const completeRegistation = async (token: string, password: string): Promise> => { + const { data } = await axios.post>(get(endpoint), { token, password }) + return data; + } + + const registerAdmin = async (username: string, password: string): Promise> => { + const { data } = await axios.post>(get(endpoint), { admin_username:username, password }) + return data; + } + + return { + createSignupLink, + getStatus, + completeRegistation, + registerAdmin + } +} + +export const registationPlugin = (regEndpoint: MaybeRef): PiniaPlugin => { + + return ({ store }: PiniaPluginContext): any => { + + const { loggedIn } = storeToRefs(store) + + const regApi = useRegApi(regEndpoint) + const status = shallowRef() + + 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 -- cgit