awesome, have inital authn working, auto re-authn is not yet though

This commit is contained in:
Chris Kruining 2025-05-22 16:21:58 +02:00
parent ec0ae60b10
commit 7d092176b2
No known key found for this signature in database
GPG key ID: EB894A3560CCCAD2
11 changed files with 100 additions and 45 deletions

View file

@ -4,29 +4,14 @@ import devtools from 'solid-devtools/vite';
export default defineConfig({ export default defineConfig({
vite: { vite: {
resolve: {
alias: [
{ find: '@', replacement: 'F:\\Github\\calque\\node_modules\\' },
],
},
html: { html: {
cspNonce: 'KAAS_IS_AWESOME', cspNonce: 'KAAS_IS_AWESOME',
}, },
// css: {
// postcss: {
// },
// },
plugins: [ plugins: [
devtools({ devtools({
autoname: true, autoname: true,
}), }),
solidSvg(), solidSvg(),
{
name: 'temp',
configResolved(config) {
console.log(config.resolve.alias);
},
}
], ],
}, },
solid: { solid: {

View file

@ -1,5 +1,5 @@
{ {
"provider_urls": [ "provider_urls": [
"http://localhost:3000/fedcm.json" "http://localhost:3000/auth/idp/api/config"
] ]
} }

View file

@ -14,10 +14,10 @@ export interface User {
} }
const USERS: User[] = [ const USERS: User[] = [
{ id: '20d701f3-0f9f-4c21-a379-81b49f755f9e', username: 'chris', credential: 'test', givenName: 'Chris', familyName: 'Kruining', picture: '', approvedClients: [] }, { id: '20d701f3-0f9f-4c21-a379-81b49f755f9e', username: 'chris', credential: 'test', givenName: 'Chris', familyName: 'Kruining', picture: '', approvedClients: [ '/auth/client' ] },
{ id: '10199201-1564-47db-b67b-07088ff05de8', username: 'john', credential: 'test', givenName: 'John', familyName: 'Doe', picture: '', approvedClients: [] }, { id: '10199201-1564-47db-b67b-07088ff05de8', username: 'john', credential: 'test', givenName: 'John', familyName: 'Doe', picture: '', approvedClients: [ '/auth/client' ] },
{ id: '633c44b3-8d3d-4dd1-8e1c-7de355d6dced', username: 'chris_alt', credential: 'test', givenName: 'Chris', familyName: 'Kruining', picture: '', approvedClients: [] }, { id: '633c44b3-8d3d-4dd1-8e1c-7de355d6dced', username: 'chris_alt', credential: 'test', givenName: 'Chris', familyName: 'Kruining', picture: '', approvedClients: [ '/auth/client' ] },
{ id: 'b9759798-8a41-4961-94a6-feb2372de9cf', username: 'john_alt', credential: 'test', givenName: 'John', familyName: 'Doe', picture: '', approvedClients: [] }, { id: 'b9759798-8a41-4961-94a6-feb2372de9cf', username: 'john_alt', credential: 'test', givenName: 'John', familyName: 'Doe', picture: '', approvedClients: [ '/auth/client' ] },
]; ];
export const getUser = (idOrUsername: string) => { export const getUser = (idOrUsername: string) => {
@ -41,9 +41,13 @@ export const signOut = async () => {
}; };
export const use = (...middlewares: Middleware[]) => { export const use = (...middlewares: Middleware[]) => {
return (event: APIEvent) => { return async (event: APIEvent) => {
console.log(`received ${event.request.url}`);
for (const handler of middlewares) { for (const handler of middlewares) {
const response = handler(event); const response = await handler(event);
console.log(response?.status);
if (response !== undefined) { if (response !== undefined) {
return response; return response;
@ -76,6 +80,8 @@ export const assertApiSession = async ({ request, locals }: APIEvent) => {
const user = await getSession(); const user = await getSession();
if (user === undefined) { if (user === undefined) {
console.log('user session not available');
return json({ error: 'not signed in' }, { status: 401 }); return json({ error: 'not signed in' }, { status: 401 });
} }

View file

@ -2,13 +2,16 @@ import { onMount } from "solid-js";
export default function Index() { export default function Index() {
onMount(async () => { onMount(async () => {
try { const user = await fetch('/auth/idp/api/user-info').then(r => r.json());
// navigator.login.setStatus('logged-in');
console.log(user);
if (user === undefined || true) {
try {
const credential = await navigator.credentials.get({ const credential = await navigator.credentials.get({
identity: { identity: {
providers: [{ providers: [{
configURL: new URL('http://localhost:3000/fedcm.json'), configURL: new URL('http://localhost:3000/auth/idp/api/config'),
clientId: '/auth/client', clientId: '/auth/client',
nonce: 'kaas', nonce: 'kaas',
loginHint: 'chris', loginHint: 'chris',
@ -16,13 +19,14 @@ export default function Index() {
mode: 'passive', mode: 'passive',
context: undefined, context: undefined,
}, },
mediation: undefined, mediation: 'silent',
}); });
console.log(credential); console.log(credential);
} catch(e) { } catch(e) {
console.error(e); console.error(e);
} }
}
}); });
return 'WOOT'; return 'WOOT';

View file

@ -4,5 +4,5 @@ import { APIEvent } from "@solidjs/start/server";
export const GET = ({ request }: APIEvent) => { export const GET = ({ request }: APIEvent) => {
console.error(`url not found ${request.url}`); console.error(`url not found ${request.url}`);
// return json({ error: `url ${request.url} is not implemented` }, { status: 404 }) return json({ error: `url ${request.url} is not implemented` }, { status: 404 })
}; };

View file

@ -2,8 +2,8 @@ import { json } from "@solidjs/router";
import { APIEvent } from "@solidjs/start/server"; import { APIEvent } from "@solidjs/start/server";
import { assertApiSession, assertCsrf, use, User } from "~/features/auth"; import { assertApiSession, assertCsrf, use, User } from "~/features/auth";
export const GET = use(assertCsrf, assertApiSession, async (event: APIEvent) => { export const GET = use(assertCsrf, assertApiSession, async ({ locals }: APIEvent) => {
const user = event.locals.user as User; const { user } = locals;
console.log('accounts endpoint', user); console.log('accounts endpoint', user);

View file

@ -0,0 +1,33 @@
import { json } from "@solidjs/router";
import { APIEvent } from "@solidjs/start/server";
export const GET = async ({ request }: APIEvent) => {
console.log('config requested', request);
return json({
"accounts_endpoint": "/auth/idp/api/accounts",
"client_metadata_endpoint": "/auth/idp/api/metadata",
"id_assertion_endpoint": "/auth/idp/api/idtokens",
"disconnect_endpoint": "/auth/idp/api/disconnect",
"login_url": "/auth/idp",
"modes": {
"active": {
"supports_use_other_account": true
}
},
"branding": {
"background_color": "#6200ee",
"color": "#ffffff",
"icons": [
{
"url": "/images/favicon.dark.svg",
"size": 512
},
{
"url": "/images/favicon.light.svg",
"size": 512
}
]
}
});
};

View file

@ -3,9 +3,13 @@ import { APIEvent } from "@solidjs/start/server";
import { use, assertCsrf, assertApiSession } from "~/features/auth"; import { use, assertCsrf, assertApiSession } from "~/features/auth";
export const POST = use(assertCsrf, assertApiSession, async ({ request }: APIEvent) => { export const POST = use(assertCsrf, assertApiSession, async ({ request }: APIEvent) => {
console.log(request); console.log('id token requested', request.url);
return json({ return json({
token: 'THIS IS A BEAUTIFUL TOKEN', token: 'THIS IS A BEAUTIFUL TOKEN',
}, {
headers: {
'Set-Login': 'logged-in'
}
}); });
}); });

View file

@ -3,6 +3,8 @@ import { APIEvent } from "@solidjs/start/server";
import { getUser, signIn } from "~/features/auth"; import { getUser, signIn } from "~/features/auth";
export const POST = async ({ request }: APIEvent) => { export const POST = async ({ request }: APIEvent) => {
console.log('login requested', request.url);
const formData = await request.formData(); const formData = await request.formData();
const username = formData.get('username'); const username = formData.get('username');
const password = formData.get('password'); const password = formData.get('password');
@ -27,7 +29,9 @@ export const POST = async ({ request }: APIEvent) => {
await signIn(user); await signIn(user);
return redirect('/auth/client', { const token = 'THIS IS MY AWESOME TOKEN';
return json({ token }, {
headers: { headers: {
'Set-Login': 'logged-in', 'Set-Login': 'logged-in',
} }

View file

@ -2,6 +2,8 @@ import { json } from "@solidjs/router";
import { APIEvent } from "@solidjs/start/server"; import { APIEvent } from "@solidjs/start/server";
export const GET = ({ request }: APIEvent) => { export const GET = ({ request }: APIEvent) => {
console.log('metadata requested', request.url);
return json({ return json({
privacy_policy_url: '/privacy-policy.txt', privacy_policy_url: '/privacy-policy.txt',
terms_of_service_url: '/terms-of-service.txt', terms_of_service_url: '/terms-of-service.txt',

View file

@ -0,0 +1,17 @@
import { json } from "@solidjs/router";
import { APIEvent } from "@solidjs/start/server";
import { assertApiSession, use } from "~/features/auth";
export const GET = use(assertApiSession, async ({ locals }: APIEvent) => {
const { user } = locals;
return json({
id: user.id,
given_name: user.givenName,
name: `${user.givenName} ${user.familyName}`,
email: user.username,
picture: user.picture,
login_hints: [user.username],
approved_clients: user.approvedClients,
});
});