From e01aae6c30f18003ceae07c092cddeb488e8f472 Mon Sep 17 00:00:00 2001 From: vnugent Date: Sun, 7 Jan 2024 01:53:03 -0500 Subject: package updates & social auth setup --- front-end/src/App.vue | 10 +++- front-end/src/main.ts | 2 +- front-end/src/store/socialMfaPlugin.ts | 80 +++++++++++++++++-------- front-end/src/views/Login/components/Social.vue | 26 ++++++-- front-end/src/views/Login/index.vue | 4 +- front-end/src/views/Login/social/[type].vue | 3 +- 6 files changed, 90 insertions(+), 35 deletions(-) (limited to 'front-end/src') diff --git a/front-end/src/App.vue b/front-end/src/App.vue index d6ac36f..2f29fde 100644 --- a/front-end/src/App.vue +++ b/front-end/src/App.vue @@ -3,7 +3,7 @@ {{ metaTile }} - + @@ -15,6 +15,7 @@ import { computed } from 'vue'; import { useStore } from './store'; import { storeToRefs } from 'pinia'; import Environment from './bootstrap/Environment.vue'; +import { apiCall } from '@vnuge/vnlib.browser'; const store = useStore() const { siteTitle, pageTitle } = storeToRefs(store) @@ -22,6 +23,13 @@ const { siteTitle, pageTitle } = storeToRefs(store) //Compute meta title from the default site title and the page title const metaTile = computed(() => `${pageTitle.value} | ${siteTitle.value}`) +const logout = () => { + apiCall(async () => { + const { logout } = await store.socialOauth() + await logout() + }) +} + store.setSiteTitle('CMNext Admin') store.setPageTitle('Blog') diff --git a/front-end/src/main.ts b/front-end/src/main.ts index cda44fa..4d62df4 100644 --- a/front-end/src/main.ts +++ b/front-end/src/main.ts @@ -97,7 +97,7 @@ createVnApp({ //Enable mfa with totp settings plugin (optional pki config) .use(mfaSettingsPlugin('/account/mfa', '/account/pki')) //Setup social mfa plugin - .use(socialMfaPlugin) + .use(socialMfaPlugin()) //Setup blog state .use(cmnextAdminPlugin(router, 'https://cdn.ckeditor.com/ckeditor5/40.0.0/super-build/ckeditor.js', 15)) diff --git a/front-end/src/store/socialMfaPlugin.ts b/front-end/src/store/socialMfaPlugin.ts index d328399..b9bce27 100644 --- a/front-end/src/store/socialMfaPlugin.ts +++ b/front-end/src/store/socialMfaPlugin.ts @@ -1,42 +1,70 @@ - import 'pinia' -import { } from 'vue'; -import { useSocialOauthLogin, createSocialMethod, useUser } from '@vnuge/vnlib.browser' -import { } from '@vueuse/core'; +import { MaybeRef } from 'vue'; +import { useSocialOauthLogin, useUser, SocialOAuthPortal, fromPortals, useAxios } from '@vnuge/vnlib.browser' +import { get } from '@vueuse/core'; import { PiniaPluginContext, PiniaPlugin, storeToRefs } from 'pinia' -import { } from 'lodash-es'; +import { defer } from 'lodash-es'; + +type SocialMfaPlugin = ReturnType declare module 'pinia' { export interface PiniaCustomProperties { - socialOauth: ReturnType + socialOauth(): Promise } } -export const socialMfaPlugin: PiniaPlugin = ({ store }: PiniaPluginContext) => { - - const { } = storeToRefs(store) - const { logout } = useUser() +export const socialMfaPlugin = (portalEndpoint?: MaybeRef): PiniaPlugin => { - //Setup social providers - const socialOauth = useSocialOauthLogin([ - //createSocialMethod('github', '/login/social/github'), - //createSocialMethod('discord', '/login/social/discord'), - ]) + return ({ store }: PiniaPluginContext) => { - /** - * Override the logout function to default to a social logout, - * if the social logout fails, then we will logout the user - */ + const { } = storeToRefs(store) + const { logout } = useUser() - const logoutFunc = socialOauth.logout; + /** + * Override the logout function to default to a social logout, + * if the social logout fails, then we will logout the user + */ + const setLogoutMethod = (socialOauth: SocialMfaPlugin) => { + const logoutFunc = socialOauth.logout; - (socialOauth as any).logout = async () => { - if (await logoutFunc() === false) { - await logout() + (socialOauth as any).logout = async () => { + if (await logoutFunc() === false) { + await logout() + } + } } - } - return { - socialOauth + const _loadPromise = new Promise((resolve, reject) => { + + if(get(portalEndpoint) == null) { + const socialOauth = useSocialOauthLogin([]) + setLogoutMethod(socialOauth) + return resolve(socialOauth) + } + + defer(async () => { + try { + //Get axios instance + const axios = useAxios(null) + + //Get all enabled portals + const { data } = await axios.get(get(portalEndpoint)); + //Setup social providers from server portals + const socialOauth = useSocialOauthLogin(fromPortals(data)); + setLogoutMethod(socialOauth); + + resolve(socialOauth) + + } catch (error) { + reject(error) + } + }) + }) + + const socialOauth = () => _loadPromise + + return { + socialOauth, + } } } \ No newline at end of file diff --git a/front-end/src/views/Login/components/Social.vue b/front-end/src/views/Login/components/Social.vue index 2cea930..4d22074 100644 --- a/front-end/src/views/Login/components/Social.vue +++ b/front-end/src/views/Login/components/Social.vue @@ -1,22 +1,21 @@ \ No newline at end of file diff --git a/front-end/src/views/Login/index.vue b/front-end/src/views/Login/index.vue index 5d8f298..6a55aeb 100644 --- a/front-end/src/views/Login/index.vue +++ b/front-end/src/views/Login/index.vue @@ -62,7 +62,9 @@ const submitLogout = async () => { //Submit logout request await apiCall(async ({ toaster }) => { // Attempt to logout - await store.socialOauth.logout() + const { logout } = await store.socialOauth() + await logout() + // Push a new toast message toaster.general.success({ id: 'logout-success', diff --git a/front-end/src/views/Login/social/[type].vue b/front-end/src/views/Login/social/[type].vue index 68e8b77..51da94f 100644 --- a/front-end/src/views/Login/social/[type].vue +++ b/front-end/src/views/Login/social/[type].vue @@ -64,7 +64,8 @@ tryOnMounted(() => defer(() => { apiCall(async ({ toaster }) => { try{ //Complete the login - await store.socialOauth.completeLogin(); + const { completeLogin } = await store.socialOauth(); + await completeLogin() toaster.general.success({ title:'Login Successful', -- cgit