feat: reach an initial working stage
This commit is contained in:
parent
8db323b63f
commit
34cfee7cff
34 changed files with 1078 additions and 684 deletions
|
|
@ -1,68 +1,61 @@
|
|||
import { type LoaderFunctionArgs, redirect } from 'react-router';
|
||||
import { type LoaderFunctionArgs, Session, redirect } from 'react-router';
|
||||
import type { LoadContext } from '~/server';
|
||||
import type { AuthSession, OidcFlowSession } from '~/server/web/sessions';
|
||||
import { finishAuthFlow, formatError } from '~/utils/oidc';
|
||||
import { send } from '~/utils/res';
|
||||
import { commitSession, getSession } from '~/utils/sessions.server';
|
||||
import { hp_getConfig, hp_getSingleton } from '~server/context/global';
|
||||
|
||||
export async function loader({ request }: LoaderFunctionArgs) {
|
||||
const { oidc } = hp_getConfig();
|
||||
try {
|
||||
if (!oidc) {
|
||||
throw new Error('OIDC is not enabled');
|
||||
}
|
||||
|
||||
hp_getSingleton('oidc_client');
|
||||
} catch {
|
||||
return send({ error: 'OIDC is not enabled' }, { status: 400 });
|
||||
export async function loader({
|
||||
request,
|
||||
context,
|
||||
}: LoaderFunctionArgs<LoadContext>) {
|
||||
if (!context.oidc) {
|
||||
throw new Error('OIDC is not enabled');
|
||||
}
|
||||
|
||||
// Check if we have 0 query parameters
|
||||
const url = new URL(request.url);
|
||||
if (url.searchParams.toString().length === 0) {
|
||||
return redirect('/machines');
|
||||
return redirect('/login');
|
||||
}
|
||||
|
||||
const session = await getSession(request.headers.get('Cookie'));
|
||||
if (session.has('hsApiKey')) {
|
||||
return redirect('/machines');
|
||||
const session = await context.sessions.getOrCreate<OidcFlowSession>(request);
|
||||
if (session.get('state') !== 'flow') {
|
||||
return redirect('/login'); // Haven't started an OIDC flow
|
||||
}
|
||||
|
||||
const codeVerifier = session.get('oidc_code_verif');
|
||||
const state = session.get('oidc_state');
|
||||
const nonce = session.get('oidc_nonce');
|
||||
const redirectUri = session.get('oidc_redirect_uri');
|
||||
|
||||
if (!codeVerifier || !state || !nonce || !redirectUri) {
|
||||
const payload = session.get('oidc')!;
|
||||
const { code_verifier, state, nonce, redirect_uri } = payload;
|
||||
if (!code_verifier || !state || !nonce || !redirect_uri) {
|
||||
return send({ error: 'Missing OIDC state' }, { status: 400 });
|
||||
}
|
||||
|
||||
// Reconstruct the redirect URI using the query parameters
|
||||
// and the one we saved in the session
|
||||
const flowRedirectUri = new URL(redirectUri);
|
||||
const flowRedirectUri = new URL(redirect_uri);
|
||||
flowRedirectUri.search = url.search;
|
||||
|
||||
const flowOptions = {
|
||||
redirect_uri: flowRedirectUri.toString(),
|
||||
codeVerifier,
|
||||
code_verifier,
|
||||
state,
|
||||
nonce: nonce === '<none>' ? undefined : nonce,
|
||||
};
|
||||
|
||||
try {
|
||||
const user = await finishAuthFlow(oidc, flowOptions);
|
||||
session.set('user', user);
|
||||
session.unset('oidc_code_verif');
|
||||
session.unset('oidc_state');
|
||||
session.unset('oidc_nonce');
|
||||
const user = await finishAuthFlow(context.oidc, flowOptions);
|
||||
session.unset('oidc');
|
||||
const userSession = session as Session<AuthSession>;
|
||||
|
||||
// TODO: This is breaking, to stop the "over-generation" of API
|
||||
// keys because they are currently non-deletable in the headscale
|
||||
// database. Look at this in the future once we have a solution
|
||||
// or we have permissioned API keys.
|
||||
session.set('hsApiKey', oidc.headscale_api_key);
|
||||
userSession.set('user', user);
|
||||
userSession.set('api_key', context.config.oidc?.headscale_api_key!);
|
||||
userSession.set('state', 'auth');
|
||||
return redirect('/machines', {
|
||||
headers: {
|
||||
'Set-Cookie': await commitSession(session),
|
||||
'Set-Cookie': await context.sessions.commit(userSession),
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue