From d0322dc62e9484be4c2dfda4a68cfc6807272b4a Mon Sep 17 00:00:00 2001 From: ajdj100 Date: Fri, 12 Dec 2025 10:30:13 -0500 Subject: [PATCH 1/5] added discord scope --- api/src/routes/auth.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/routes/auth.js b/api/src/routes/auth.js index c736f33..bed32af 100644 --- a/api/src/routes/auth.js +++ b/api/src/routes/auth.js @@ -18,13 +18,13 @@ passport.use(new OpenIDConnectStrategy({ clientID: process.env.AUTH_CLIENT_ID, clientSecret: process.env.AUTH_CLIENT_SECRET, callbackURL: process.env.AUTH_REDIRECT_URI, - scope: ['openid', 'profile'] + scope: ['openid', 'profile', 'discord'] }, async function verify(issuer, sub, profile, jwtClaims, accessToken, refreshToken, params, cb) { console.log('--- OIDC verify() called ---'); console.log('issuer:', issuer); console.log('sub:', sub); - // console.log('profile:', JSON.stringify(profile, null, 2)); + console.log('params:', params); console.log('profile:', profile); console.log('id_token claims:', JSON.stringify(jwtClaims, null, 2)); console.log('preferred_username:', jwtClaims?.preferred_username); From 7ac83b532b5b06bbed4c33241fd9861df6dffc84 Mon Sep 17 00:00:00 2001 From: ajdj100 Date: Sun, 14 Dec 2025 22:31:08 -0500 Subject: [PATCH 2/5] removed nuisance logging --- api/src/routes/members.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/api/src/routes/members.ts b/api/src/routes/members.ts index 26e3fa8..3e574aa 100644 --- a/api/src/routes/members.ts +++ b/api/src/routes/members.ts @@ -38,18 +38,11 @@ router.get('/me', [requireLogin], async (req, res) => { try { const { id, name, state } = await getUserData(req.user.id); - // const LOAData = await pool.query( - // `SELECT * - // FROM leave_of_absences - // WHERE member_id = ? - // AND deleted = 0 - // AND UTC_TIMESTAMP() BETWEEN start_date AND end_date;`, req.user.id); const LOAData = await getUserActiveLOA(req.user.id); const roleData = await getUserRoles(req.user.id); const userDataFull = { id, name, state, LOAData, roleData }; - console.log(userDataFull) res.status(200).json(userDataFull); } catch (error) { console.error('Error fetching user data:', error); From a6002dadb5ea1bd9b5f2231ffe96e4e050f8f52a Mon Sep 17 00:00:00 2001 From: ajdj100 Date: Sun, 14 Dec 2025 22:33:10 -0500 Subject: [PATCH 3/5] implemented account claiming system --- api/src/routes/auth.ts | 47 +++++++++++++++++++++++-------- api/src/services/memberService.ts | 11 ++++++-- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/api/src/routes/auth.ts b/api/src/routes/auth.ts index c078585..ee9d6ac 100644 --- a/api/src/routes/auth.ts +++ b/api/src/routes/auth.ts @@ -10,10 +10,14 @@ import { Role } from '@app/shared/types/roles'; import pool from '../db'; import { requireLogin } from '../middleware/auth'; import { getUserRoles } from '../services/rolesService'; -import { getUserState } from '../services/memberService'; +import { getUserState, mapDiscordtoID } from '../services/memberService'; import { MemberState } from '@app/shared/types/member'; +import { toDateTime } from '@app/shared/utils/time'; const querystring = require('querystring'); +function parseJwt(token) { + return JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString()); +} passport.use(new OpenIDConnectStrategy({ issuer: process.env.AUTH_ISSUER, @@ -29,10 +33,11 @@ passport.use(new OpenIDConnectStrategy({ console.log('--- OIDC verify() called ---'); console.log('issuer:', issuer); console.log('sub:', sub); - console.log('params:', params); + // console.log('discord:', discord); console.log('profile:', profile); - console.log('id_token claims:', JSON.stringify(jwtClaims, null, 2)); - console.log('preferred_username:', jwtClaims?.preferred_username); + console.log('jwt: ', parseJwt(jwtClaims)); + console.log('params:', params); + try { var con = await pool.getConnection(); @@ -47,14 +52,33 @@ passport.use(new OpenIDConnectStrategy({ memberId = existing[0].id; } else { //otherwise: create account - const username = sub.username; + const jwt = parseJwt(jwtClaims); + const discordID = jwt.discord.id as number; - const result = await con.query( - `INSERT INTO members (name, authentik_sub, authentik_issuer) VALUES (?, ?, ?)`, - [username, sub, issuer] - ) - memberId = Number(result.insertId); + //check if account is available to claim + let memberId = await mapDiscordtoID(discordID); + + if (memberId === null) { + console.log('new account'); + // create new account + const username = sub.username; + const result = await con.query( + `INSERT INTO members (name, authentik_sub, authentik_issuer) VALUES (?, ?, ?)`, + [username, sub, issuer] + ) + memberId = Number(result.insertId); + } else { + console.log('claim account'); + // claim existing account + const result = await con.query( + `UPDATE members SET authentik_sub = ?, authentik_issuer = ? WHERE id = ?;`, + [sub, issuer, memberId] + ) + } } + + await con.query(`UPDATE members SET last_login = ? WHERE id = ?`, [toDateTime(new Date()), memberId]) + await con.commit(); return cb(null, { memberId }); } catch (error) { @@ -116,11 +140,10 @@ passport.deserializeUser(function (user, cb) { var userData: { id: number, name: string, roles: Role[], state: MemberState }; try { var con = await pool.getConnection(); - let userResults = await con.query(`SELECT id, name FROM members WHERE id = ?;`, [memberID]) userData = userResults[0]; let userRoles = await getUserRoles(memberID); - userData.roles = userRoles; + userData.roles = userRoles || []; userData.state = await getUserState(memberID); } catch (error) { console.error(error) diff --git a/api/src/services/memberService.ts b/api/src/services/memberService.ts index 66b5917..6381ad1 100644 --- a/api/src/services/memberService.ts +++ b/api/src/services/memberService.ts @@ -15,9 +15,8 @@ export async function setUserState(userID: number, state: MemberState) { } export async function getUserState(user: number): Promise { - let out = await pool.query(`SELECT state FROM members WHERE id = ?`, [user]); - console.log('hi') - return (out[0].state as MemberState); + let out = await pool.query(`SELECT state FROM members WHERE id = ?`, [user]); + return (out[0].state as MemberState); } export async function getMemberSettings(id: number): Promise { @@ -54,4 +53,10 @@ export async function getMembersFull(ids: number[]): Promise { const sql = `SELECT * FROM view_member_rank_unit_status_latest WHERE member_id IN (?);`; const res: Member[] = await pool.query(sql, [ids]); return res; +} + +export async function mapDiscordtoID(id: number): Promise { + const sql = `SELECT id FROM members WHERE discord_id = ?;` + let res = await pool.query(sql, [id]); + return res.length > 0 ? res[0].id : null; } \ No newline at end of file From b99d6653f8bbda845396b93b8660e4234975ebfb Mon Sep 17 00:00:00 2001 From: ajdj100 Date: Sun, 14 Dec 2025 22:39:07 -0500 Subject: [PATCH 4/5] disabled mega logging --- api/src/routes/auth.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/api/src/routes/auth.ts b/api/src/routes/auth.ts index ee9d6ac..56fef9b 100644 --- a/api/src/routes/auth.ts +++ b/api/src/routes/auth.ts @@ -30,13 +30,13 @@ passport.use(new OpenIDConnectStrategy({ scope: ['openid', 'profile', 'discord'] }, async function verify(issuer, sub, profile, jwtClaims, accessToken, refreshToken, params, cb) { - console.log('--- OIDC verify() called ---'); - console.log('issuer:', issuer); - console.log('sub:', sub); - // console.log('discord:', discord); - console.log('profile:', profile); - console.log('jwt: ', parseJwt(jwtClaims)); - console.log('params:', params); + // console.log('--- OIDC verify() called ---'); + // console.log('issuer:', issuer); + // console.log('sub:', sub); + // // console.log('discord:', discord); + // console.log('profile:', profile); + // console.log('jwt: ', parseJwt(jwtClaims)); + // console.log('params:', params); try { @@ -80,6 +80,7 @@ passport.use(new OpenIDConnectStrategy({ await con.query(`UPDATE members SET last_login = ? WHERE id = ?`, [toDateTime(new Date()), memberId]) await con.commit(); + console.log(memberId); return cb(null, { memberId }); } catch (error) { await con.rollback(); From a335ce862ddadd96462f8bd2b7652b8e642528d4 Mon Sep 17 00:00:00 2001 From: ajdj100 Date: Sun, 14 Dec 2025 22:47:18 -0500 Subject: [PATCH 5/5] fixed post account creation/claim flow. This may fix #93 --- api/src/routes/auth.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/api/src/routes/auth.ts b/api/src/routes/auth.ts index 56fef9b..3b34c23 100644 --- a/api/src/routes/auth.ts +++ b/api/src/routes/auth.ts @@ -46,7 +46,7 @@ passport.use(new OpenIDConnectStrategy({ //lookup existing user const existing = await con.query(`SELECT id FROM members WHERE authentik_issuer = ? AND authentik_sub = ? LIMIT 1;`, [issuer, sub]); - let memberId; + let memberId: number; //if member exists if (existing.length > 0) { memberId = existing[0].id; @@ -56,10 +56,9 @@ passport.use(new OpenIDConnectStrategy({ const discordID = jwt.discord.id as number; //check if account is available to claim - let memberId = await mapDiscordtoID(discordID); + memberId = await mapDiscordtoID(discordID); if (memberId === null) { - console.log('new account'); // create new account const username = sub.username; const result = await con.query( @@ -68,7 +67,6 @@ passport.use(new OpenIDConnectStrategy({ ) memberId = Number(result.insertId); } else { - console.log('claim account'); // claim existing account const result = await con.query( `UPDATE members SET authentik_sub = ?, authentik_issuer = ? WHERE id = ?;`, @@ -80,7 +78,6 @@ passport.use(new OpenIDConnectStrategy({ await con.query(`UPDATE members SET last_login = ? WHERE id = ?`, [toDateTime(new Date()), memberId]) await con.commit(); - console.log(memberId); return cb(null, { memberId }); } catch (error) { await con.rollback();