webadmin: remove the implicit flow
we now use pkce . main advantage is that we don't see the access token in the url anymore. in pkce, the auth code by itself is useless. need the verifier. fixes #844
This commit is contained in:
@@ -8,7 +8,7 @@ import { onMounted, onUnmounted, ref, useTemplateRef, provide } from 'vue';
|
||||
import { Notification, InputDialog, fetcher } from '@cloudron/pankow';
|
||||
import { setLanguage } from './i18n.js';
|
||||
import { API_ORIGIN, TOKEN_TYPES } from './constants.js';
|
||||
import { redirectIfNeeded } from './utils.js';
|
||||
import { redirectIfNeeded, startAuthFlow } from './utils.js';
|
||||
import ProfileModel from './models/ProfileModel.js';
|
||||
import ProvisionModel from './models/ProvisionModel.js';
|
||||
import NotificationsModel from './models/NotificationsModel.js';
|
||||
@@ -436,8 +436,8 @@ onMounted(async () => {
|
||||
if (!localStorage.token) {
|
||||
localStorage.setItem('redirectToHash', window.location.hash);
|
||||
|
||||
// start oidc flow
|
||||
window.location.href = `${API_ORIGIN}/openid/auth?client_id=` + (API_ORIGIN ? TOKEN_TYPES.ID_DEVELOPMENT : TOKEN_TYPES.ID_WEBADMIN) + '&scope=openid email profile&response_type=code token&redirect_uri=' + window.location.origin + '/authcallback.html';
|
||||
const clientId = API_ORIGIN ? TOKEN_TYPES.ID_DEVELOPMENT : TOKEN_TYPES.ID_WEBADMIN;
|
||||
window.location.href = await startAuthFlow(clientId, API_ORIGIN);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { marked } from 'marked';
|
||||
import { Button, PasswordInput, FormGroup, TextInput } from '@cloudron/pankow';
|
||||
import PublicPageLayout from '../components/PublicPageLayout.vue';
|
||||
import ProfileModel from '../models/ProfileModel.js';
|
||||
import { startAuthFlow } from '../utils.js';
|
||||
|
||||
const profileModel = ProfileModel.create();
|
||||
|
||||
@@ -89,7 +90,7 @@ async function onSubmit() {
|
||||
// set token to autologin on first oidc flow
|
||||
localStorage.cloudronFirstTimeToken = result.accessToken;
|
||||
|
||||
dashboardUrl.value = '/openid/auth?client_id=cid-webadmin&scope=openid email profile&response_type=code token&redirect_uri=' + window.location.origin + '/authcallback.html';
|
||||
dashboardUrl.value = await startAuthFlow('cid-webadmin', '');
|
||||
|
||||
busy.value = false;
|
||||
mode.value = MODE.DONE;
|
||||
|
||||
+33
-2
@@ -660,6 +660,35 @@ function parseFullBackupPath(fullPath) {
|
||||
return { prefix, remotePath };
|
||||
}
|
||||
|
||||
function base64urlEncode(buffer) {
|
||||
return btoa(String.fromCharCode(...buffer))
|
||||
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
||||
}
|
||||
|
||||
function generateCodeVerifier() {
|
||||
const array = new Uint8Array(32);
|
||||
crypto.getRandomValues(array);
|
||||
return base64urlEncode(array);
|
||||
}
|
||||
|
||||
async function computeCodeChallenge(verifier) {
|
||||
const hash = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier));
|
||||
return base64urlEncode(new Uint8Array(hash));
|
||||
}
|
||||
|
||||
async function startAuthFlow(clientId, apiOrigin) {
|
||||
const codeVerifier = generateCodeVerifier();
|
||||
const codeChallenge = await computeCodeChallenge(codeVerifier);
|
||||
|
||||
sessionStorage.setItem('pkce_code_verifier', codeVerifier);
|
||||
sessionStorage.setItem('pkce_client_id', clientId);
|
||||
sessionStorage.setItem('pkce_api_origin', apiOrigin || '');
|
||||
|
||||
const redirectUri = window.location.origin + '/authcallback.html';
|
||||
const base = apiOrigin || '';
|
||||
return `${base}/openid/auth?client_id=${clientId}&scope=openid email profile&response_type=code&redirect_uri=${redirectUri}&code_challenge=${codeChallenge}&code_challenge_method=S256`;
|
||||
}
|
||||
|
||||
// named exports
|
||||
export {
|
||||
renderSafeMarkdown,
|
||||
@@ -679,7 +708,8 @@ export {
|
||||
getColor,
|
||||
prettySchedule,
|
||||
parseSchedule,
|
||||
parseFullBackupPath
|
||||
parseFullBackupPath,
|
||||
startAuthFlow
|
||||
};
|
||||
|
||||
// default export
|
||||
@@ -701,5 +731,6 @@ export default {
|
||||
getColor,
|
||||
prettySchedule,
|
||||
parseSchedule,
|
||||
parseFullBackupPath
|
||||
parseFullBackupPath,
|
||||
startAuthFlow
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { ref, useTemplateRef, onMounted } from 'vue';
|
||||
import { Button, Checkbox, FormGroup, TextInput, PasswordInput, EmailInput } from '@cloudron/pankow';
|
||||
import ProvisionModel from '../models/ProvisionModel.js';
|
||||
import { redirectIfNeeded } from '../utils.js';
|
||||
import { redirectIfNeeded, startAuthFlow } from '../utils.js';
|
||||
|
||||
const provisionModel = ProvisionModel.create();
|
||||
|
||||
@@ -59,7 +59,7 @@ async function onOwnerSubmit() {
|
||||
// set token to autologin on first oidc flow
|
||||
localStorage.cloudronFirstTimeToken = result;
|
||||
|
||||
window.location.href = '/openid/auth?client_id=cid-webadmin&scope=openid email profile&response_type=code token&redirect_uri=' + window.location.origin + '/authcallback.html';
|
||||
window.location.href = await startAuthFlow('cid-webadmin', '');
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
|
||||
Reference in New Issue
Block a user