Desktop OIDC: full page nav to localhost, meta redirect back
SPA navigates to 127.0.0.1:18901/oidc/start, passing ret URL. Go opens browser, waits for callback, saves token, returns HTML with <meta refresh> back to Wails app with ?desktop=1&token=TOKEN. main.ts extracts token from URL on reload.
This commit is contained in:
@@ -103,7 +103,9 @@ export async function startLogin(): Promise<void> {
|
||||
|
||||
if (isDesktop) {
|
||||
const apiUrl = getConfig().apiUrl || ''
|
||||
throw new Error('DESKTOP_OIDC:' + apiUrl)
|
||||
const ret = encodeURIComponent(location.origin + location.pathname.replace(/\/$/, '') + '?desktop=1')
|
||||
location.href = `http://127.0.0.1:18901/oidc/start?apiUrl=${encodeURIComponent(apiUrl)}&ret=${ret}`
|
||||
return
|
||||
}
|
||||
|
||||
location.href = `${cfg.authorization_endpoint.replace(/\/$/, '')}/?${params}`
|
||||
|
||||
@@ -1,10 +1,26 @@
|
||||
import { mount } from 'svelte'
|
||||
import App from './App.svelte'
|
||||
import './app.css'
|
||||
import { initConfig } from '$lib/config'
|
||||
import { initConfig, setConfig, getConfig } from '$lib/config'
|
||||
|
||||
function handleDesktopToken() {
|
||||
const params = new URLSearchParams(location.search)
|
||||
const token = params.get('token')
|
||||
if (token && new URLSearchParams(location.search).has('desktop')) {
|
||||
const apiUrl = getConfig().apiUrl || ''
|
||||
setConfig({ apiUrl, token, isDesktop: true })
|
||||
initConfig({ apiUrl, token, isDesktop: true })
|
||||
params.delete('token')
|
||||
const q = params.toString()
|
||||
history.replaceState(null, '', location.pathname + (q ? '?' + q : ''))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function start() {
|
||||
initConfig()
|
||||
handleDesktopToken()
|
||||
|
||||
requestAnimationFrame(() => import('./lib/renderers'))
|
||||
|
||||
|
||||
@@ -72,43 +72,11 @@
|
||||
try {
|
||||
await startLogin()
|
||||
} catch (e: any) {
|
||||
const msg = e?.message || e || ''
|
||||
if (msg.startsWith('DESKTOP_OIDC:')) {
|
||||
const url = msg.substring('DESKTOP_OIDC:'.length)
|
||||
await desktopOIDC(url)
|
||||
return
|
||||
}
|
||||
error = msg || 'OIDC login failed'
|
||||
error = e.message || 'OIDC login failed'
|
||||
oidcLoggingIn = false
|
||||
}
|
||||
}
|
||||
|
||||
async function desktopOIDC(apiUrl: string) {
|
||||
try {
|
||||
const resp = await fetch(`http://127.0.0.1:18901/oidc/open?apiUrl=${encodeURIComponent(apiUrl)}`)
|
||||
const { id } = await resp.json()
|
||||
if (!id) throw new Error('No session ID')
|
||||
|
||||
for (let i = 0; i < 600; i++) {
|
||||
await new Promise(r => setTimeout(r, 500))
|
||||
const r = await fetch(`http://127.0.0.1:18901/oidc/result?id=${id}`)
|
||||
const data = await r.json()
|
||||
if (data.token) {
|
||||
setConfig({ apiUrl, token: data.token, isDesktop: true })
|
||||
initConfig({ apiUrl, token: data.token, isDesktop: true })
|
||||
oidcLoggingIn = false
|
||||
onConnected()
|
||||
return
|
||||
}
|
||||
if (!data.pending || data.pending === 'false') break
|
||||
}
|
||||
error = 'Login timed out'
|
||||
} catch (e: any) {
|
||||
error = e?.message || 'Could not reach login service'
|
||||
}
|
||||
oidcLoggingIn = false
|
||||
}
|
||||
|
||||
function logoutOIDC() {
|
||||
oidcLogout()
|
||||
oidcUser = null
|
||||
|
||||
Reference in New Issue
Block a user