-
Notifications
You must be signed in to change notification settings - Fork 0
Add global frontend api #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
ae841a7
6bed74b
ab16fbb
9471c47
04aae96
7331544
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| import { ref } from 'vue'; | ||
| import { defineStore } from 'pinia' | ||
| import { callAdminForthApi } from '@/utils/utils'; | ||
|
yaroslav8765 marked this conversation as resolved.
|
||
|
|
||
| export const use2faApi = defineStore('2fa', () => { | ||
| const isOpened = ref(false); | ||
| const customDialogTitle = ref(''); | ||
| const resolveFn = ref<((confirmationResult: any) => void) | null>(null); | ||
| const verifyFn = ref<null | ((confirmationResult: string) => Promise<boolean> | boolean)>(null); | ||
| const rejectFn = ref<((err?: any) => void) | null>(null); | ||
| const addEventListenerForOTPInput = ref<null | (() => Promise<void>)>(null); | ||
| const doesUserHavePasskeys = ref(false); | ||
| const modalMode = ref<"totp" | "passkey">("totp"); | ||
|
|
||
| function setDoesUserHavePasskeys(value: boolean) { | ||
| doesUserHavePasskeys.value = value; | ||
| } | ||
|
|
||
| function setModalMode(mode: "totp" | "passkey") { | ||
| modalMode.value = mode; | ||
| } | ||
|
|
||
| function registerVerifyFn(fn: (confirmationResult: string) => Promise<boolean> | boolean) { | ||
| verifyFn.value = fn; | ||
| } | ||
|
|
||
| function registerRejectFn(fn: (err?: any) => void) { | ||
| rejectFn.value = fn; | ||
| } | ||
|
|
||
| function registerResolveFn(fn: (confirmationResult: any) => void) { | ||
| resolveFn.value = fn; | ||
| } | ||
|
|
||
| function registerAddEventListenerForOTPInput(fn: () => Promise<void>) { | ||
| addEventListenerForOTPInput.value = fn; | ||
| } | ||
|
|
||
| async function setCustomDialogTitle(title: string) { | ||
|
yaroslav8765 marked this conversation as resolved.
Outdated
|
||
| customDialogTitle.value = title; | ||
| } | ||
|
|
||
| async function checkIfSkipAllowModal(){ | ||
| try { | ||
| const response = await callAdminForthApi({ | ||
| method: "GET", | ||
| path: "/plugin/twofa/skip-allow-modal", | ||
| }); | ||
| if ( response.skipAllowed === true ) { | ||
| return true; | ||
| } else { | ||
| return false; | ||
| } | ||
| } catch (error) { | ||
| console.error('Error checking skip allow modal:', error); | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| async function checkIfUserHasPasskeys() { | ||
| try { | ||
| const response = await callAdminForthApi({ | ||
| method: 'GET', | ||
| path: '/plugin/passkeys/getPasskeys', | ||
| }); | ||
|
|
||
| if (response.ok) { | ||
| if (response.data.length >= 1) { | ||
| doesUserHavePasskeys.value = true; | ||
| modalMode.value = "passkey"; | ||
| } else { | ||
| doesUserHavePasskeys.value = false; | ||
| modalMode.value = "totp"; | ||
| } | ||
| } | ||
|
yaroslav8765 marked this conversation as resolved.
yaroslav8765 marked this conversation as resolved.
|
||
| } catch (error) { | ||
| console.error('Error checking passkeys:', error); | ||
| doesUserHavePasskeys.value = false; | ||
| modalMode.value = "totp"; | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| async function get2FaConfirmationResult(title?: string, verifyingCallback?: (confirmationResult: string) => Promise<boolean> | boolean) { | ||
| return new Promise(async (resolve, reject) => { | ||
| if (isOpened.value) throw new Error('Modal is already open'); | ||
| const skipAllowModal = await checkIfSkipAllowModal(); | ||
| if (skipAllowModal) { | ||
| resolve({ code: "123456" }); // dummy code | ||
| return; | ||
| } | ||
| await checkIfUserHasPasskeys(); | ||
| if (title) { | ||
| customDialogTitle.value = title; | ||
| } | ||
| isOpened.value = true; | ||
|
yaroslav8765 marked this conversation as resolved.
|
||
| if (!doesUserHavePasskeys.value && addEventListenerForOTPInput.value && typeof addEventListenerForOTPInput.value === 'function') { | ||
| await addEventListenerForOTPInput.value(); | ||
| } | ||
|
yaroslav8765 marked this conversation as resolved.
|
||
| resolveFn.value = resolve; | ||
| rejectFn.value = reject; | ||
| verifyFn.value = verifyingCallback ?? null; | ||
|
yaroslav8765 marked this conversation as resolved.
|
||
| }); | ||
| } | ||
|
|
||
| function setIsOpened(value: boolean) { | ||
| isOpened.value = value; | ||
| } | ||
|
|
||
| return { | ||
| isOpened, | ||
| customDialogTitle, | ||
| get2FaConfirmationResult, | ||
| setIsOpened, | ||
| setCustomDialogTitle, | ||
| checkIfSkipAllowModal, | ||
| registerAddEventListenerForOTPInput, | ||
| resolveFn, | ||
| verifyFn, | ||
| rejectFn, | ||
| registerVerifyFn, | ||
| registerRejectFn, | ||
| registerResolveFn, | ||
| checkIfUserHasPasskeys, | ||
| setDoesUserHavePasskeys, | ||
| setModalMode, | ||
| doesUserHavePasskeys, | ||
| modalMode, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @yaroslav8765 this is over-exposed and this is a critical issue, for users and LLM Agentic stability. In all plugins, always we need to expose from useXXAPI only methods which might be used by someone, very limited set (same method we had before exposed in window, nothing more then it), we should hide all internal implementation, e.g. setIsOpene can brake internal state, it is only get2FaConfirmationResult and maybe some couple of other methods? Please never expose "just in case someone might use it" - it will cause a lot of issues, every exposed API method should be carefully planned, otherwise we mislead. Even before LLMs plain Ctrl+Space will show user all avaialble methods, user will think he can use it and by using some internal state method he might achieven unexpected unclear behaviour Please read, ask chat to explain and remember these very basic principles:
Lets discuss all 4 principles later |
||
| }; | ||
| }); | ||
Uh oh!
There was an error while loading. Please reload this page.