feat(auth): allow automatic sso login from param (#3071)

This PR allows to automatically login to vikunja using the sso provider id specified in url parameter as discussed here : https://community.vikunja.io/t/how-to-setup-openid-automatic-redirection/2623/7

Reviewed-on: https://kolaente.dev/vikunja/vikunja/pulls/3071
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Marc <marc88@free.fr>
Co-committed-by: Marc <marc88@free.fr>
This commit is contained in:
Marc 2025-03-02 19:48:28 +00:00 committed by konrad
parent de403c365a
commit 3ad20096f3
2 changed files with 26 additions and 12 deletions

View File

@ -23,16 +23,30 @@ import {MILLISECONDS_A_SECOND} from '@/constants/date'
import {PrefixMode} from '@/modules/parseTaskText'
import type {IProvider} from '@/types/IProvider'
function redirectToProviderIfNothingElseIsEnabled() {
function redirectToSpecifiedProvider() {
const {auth} = useConfigStore()
if (
auth.local.enabled === false &&
auth.openidConnect.enabled &&
auth.openidConnect.providers?.length === 1 &&
(window.location.pathname.startsWith('/login') || window.location.pathname === '/') && // Kinda hacky, but prevents an endless loop.
window.location.search.includes('redirectToProvider=true')
) {
redirectToProvider(auth.openidConnect.providers[0])
const searchParams = new URLSearchParams(window.location.search)
if (searchParams.has('redirectToProvider')) {
const redirectToProviderValue = searchParams.get('redirectToProvider')
if (
auth.openidConnect.providers?.length === 1
&& (window.location.pathname.startsWith('/login') || window.location.pathname === '/') // Kinda hacky, but prevents an endless loop.
&& (redirectToProviderValue === null
|| redirectToProviderValue === 'true'
|| redirectToProviderValue === '1')
) {
redirectToProvider(auth.openidConnect.providers[0])
}
// let's try to find the provider to logon to !
const wantedProvider = auth.openidConnect.providers?.find(p => p.key === redirectToProviderValue)
if (wantedProvider) {
redirectToProvider(wantedProvider)
}
console.warn(`Could not find provider to redirect to.\nWanted: ${wantedProvider}\nAvailable: ${auth.openidConnect.providers?.map(p => p.key)}`)
}
}
@ -285,7 +299,7 @@ export const useAuthStore = defineStore('auth', () => {
setAuthenticated(isAuthenticated)
if (!isAuthenticated) {
setUser(null)
redirectToProviderIfNothingElseIsEnabled()
redirectToSpecifiedProvider()
}
return Promise.resolve(authenticated)
@ -419,7 +433,7 @@ export const useAuthStore = defineStore('auth', () => {
await checkAuth()
// if configured, redirect to OIDC Provider on logout
const fullProvider: IProvider = configStore.auth.openidConnect.providers?.find((p: IProvider) => p.key === loggedInVia)
const fullProvider: IProvider|undefined = configStore.auth.openidConnect.providers?.find((p: IProvider) => p.key === loggedInVia)
if (fullProvider) {
redirectToProviderOnLogout(fullProvider)
}

View File

@ -45,7 +45,7 @@ export interface ConfigState {
}
export const useConfigStore = defineStore('config', () => {
const state = reactive({
const state: ConfigState = reactive({
// These are the api defaults.
version: '',
frontendUrl: '',