Merge pull request 'account-claim' (#98) from account-claim into main
Reviewed-on: #98
This commit was merged in pull request #98.
This commit is contained in:
@@ -10,10 +10,14 @@ import { Role } from '@app/shared/types/roles';
|
|||||||
import pool from '../db';
|
import pool from '../db';
|
||||||
import { requireLogin } from '../middleware/auth';
|
import { requireLogin } from '../middleware/auth';
|
||||||
import { getUserRoles } from '../services/rolesService';
|
import { getUserRoles } from '../services/rolesService';
|
||||||
import { getUserState } from '../services/memberService';
|
import { getUserState, mapDiscordtoID } from '../services/memberService';
|
||||||
import { MemberState } from '@app/shared/types/member';
|
import { MemberState } from '@app/shared/types/member';
|
||||||
|
import { toDateTime } from '@app/shared/utils/time';
|
||||||
const querystring = require('querystring');
|
const querystring = require('querystring');
|
||||||
|
|
||||||
|
function parseJwt(token) {
|
||||||
|
return JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
|
||||||
|
}
|
||||||
|
|
||||||
passport.use(new OpenIDConnectStrategy({
|
passport.use(new OpenIDConnectStrategy({
|
||||||
issuer: process.env.AUTH_ISSUER,
|
issuer: process.env.AUTH_ISSUER,
|
||||||
@@ -23,16 +27,17 @@ passport.use(new OpenIDConnectStrategy({
|
|||||||
clientID: process.env.AUTH_CLIENT_ID,
|
clientID: process.env.AUTH_CLIENT_ID,
|
||||||
clientSecret: process.env.AUTH_CLIENT_SECRET,
|
clientSecret: process.env.AUTH_CLIENT_SECRET,
|
||||||
callbackURL: process.env.AUTH_REDIRECT_URI,
|
callbackURL: process.env.AUTH_REDIRECT_URI,
|
||||||
scope: ['openid', 'profile']
|
scope: ['openid', 'profile', 'discord']
|
||||||
}, async function verify(issuer, sub, profile, jwtClaims, accessToken, refreshToken, params, cb) {
|
}, async function verify(issuer, sub, profile, jwtClaims, accessToken, refreshToken, params, cb) {
|
||||||
|
|
||||||
// console.log('--- OIDC verify() called ---');
|
// console.log('--- OIDC verify() called ---');
|
||||||
// console.log('issuer:', issuer);
|
// console.log('issuer:', issuer);
|
||||||
// console.log('sub:', sub);
|
// console.log('sub:', sub);
|
||||||
// // console.log('profile:', JSON.stringify(profile, null, 2));
|
// // console.log('discord:', discord);
|
||||||
// console.log('profile:', profile);
|
// console.log('profile:', profile);
|
||||||
// console.log('id_token claims:', JSON.stringify(jwtClaims, null, 2));
|
// console.log('jwt: ', parseJwt(jwtClaims));
|
||||||
// console.log('preferred_username:', jwtClaims?.preferred_username);
|
// console.log('params:', params);
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var con = await pool.getConnection();
|
var con = await pool.getConnection();
|
||||||
@@ -41,20 +46,37 @@ passport.use(new OpenIDConnectStrategy({
|
|||||||
|
|
||||||
//lookup existing user
|
//lookup existing user
|
||||||
const existing = await con.query(`SELECT id FROM members WHERE authentik_issuer = ? AND authentik_sub = ? LIMIT 1;`, [issuer, sub]);
|
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 member exists
|
||||||
if (existing.length > 0) {
|
if (existing.length > 0) {
|
||||||
memberId = existing[0].id;
|
memberId = existing[0].id;
|
||||||
} else {
|
} else {
|
||||||
//otherwise: create account
|
//otherwise: create account
|
||||||
const username = sub.username;
|
const jwt = parseJwt(jwtClaims);
|
||||||
|
const discordID = jwt.discord.id as number;
|
||||||
|
|
||||||
|
//check if account is available to claim
|
||||||
|
memberId = await mapDiscordtoID(discordID);
|
||||||
|
|
||||||
|
if (memberId === null) {
|
||||||
|
// create new account
|
||||||
|
const username = sub.username;
|
||||||
const result = await con.query(
|
const result = await con.query(
|
||||||
`INSERT INTO members (name, authentik_sub, authentik_issuer) VALUES (?, ?, ?)`,
|
`INSERT INTO members (name, authentik_sub, authentik_issuer) VALUES (?, ?, ?)`,
|
||||||
[username, sub, issuer]
|
[username, sub, issuer]
|
||||||
)
|
)
|
||||||
memberId = Number(result.insertId);
|
memberId = Number(result.insertId);
|
||||||
|
} else {
|
||||||
|
// 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();
|
await con.commit();
|
||||||
return cb(null, { memberId });
|
return cb(null, { memberId });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -116,11 +138,10 @@ passport.deserializeUser(function (user, cb) {
|
|||||||
var userData: { id: number, name: string, roles: Role[], state: MemberState };
|
var userData: { id: number, name: string, roles: Role[], state: MemberState };
|
||||||
try {
|
try {
|
||||||
var con = await pool.getConnection();
|
var con = await pool.getConnection();
|
||||||
|
|
||||||
let userResults = await con.query(`SELECT id, name FROM members WHERE id = ?;`, [memberID])
|
let userResults = await con.query(`SELECT id, name FROM members WHERE id = ?;`, [memberID])
|
||||||
userData = userResults[0];
|
userData = userResults[0];
|
||||||
let userRoles = await getUserRoles(memberID);
|
let userRoles = await getUserRoles(memberID);
|
||||||
userData.roles = userRoles;
|
userData.roles = userRoles || [];
|
||||||
userData.state = await getUserState(memberID);
|
userData.state = await getUserState(memberID);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
|
|||||||
@@ -38,18 +38,11 @@ router.get('/me', [requireLogin], async (req, res) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const { id, name, state } = await getUserData(req.user.id);
|
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 LOAData = await getUserActiveLOA(req.user.id);
|
||||||
|
|
||||||
const roleData = await getUserRoles(req.user.id);
|
const roleData = await getUserRoles(req.user.id);
|
||||||
|
|
||||||
const userDataFull = { id, name, state, LOAData, roleData };
|
const userDataFull = { id, name, state, LOAData, roleData };
|
||||||
console.log(userDataFull)
|
|
||||||
res.status(200).json(userDataFull);
|
res.status(200).json(userDataFull);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching user data:', error);
|
console.error('Error fetching user data:', error);
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ export async function setUserState(userID: number, state: MemberState) {
|
|||||||
|
|
||||||
export async function getUserState(user: number): Promise<MemberState> {
|
export async function getUserState(user: number): Promise<MemberState> {
|
||||||
let out = await pool.query(`SELECT state FROM members WHERE id = ?`, [user]);
|
let out = await pool.query(`SELECT state FROM members WHERE id = ?`, [user]);
|
||||||
console.log('hi')
|
|
||||||
return (out[0].state as MemberState);
|
return (out[0].state as MemberState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,3 +54,9 @@ export async function getMembersFull(ids: number[]): Promise<Member[]> {
|
|||||||
const res: Member[] = await pool.query(sql, [ids]);
|
const res: Member[] = await pool.query(sql, [ids]);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function mapDiscordtoID(id: number): Promise<number | null> {
|
||||||
|
const sql = `SELECT id FROM members WHERE discord_id = ?;`
|
||||||
|
let res = await pool.query(sql, [id]);
|
||||||
|
return res.length > 0 ? res[0].id : null;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user