forked from cory/tildefriends
131 lines
2.8 KiB
JavaScript
131 lines
2.8 KiB
JavaScript
import * as core from './core.js';
|
|
|
|
/**
|
|
* TODOC
|
|
* @param {string} value
|
|
* @returns
|
|
*/
|
|
function unb64url(value) {
|
|
value = value.replaceAll('-', '+').replaceAll('_', '/');
|
|
let remainder = value.length % 4;
|
|
|
|
if (remainder == 3) {
|
|
return value + '=';
|
|
} else if (remainder == 2) {
|
|
return value + '==';
|
|
} else {
|
|
return value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Validates a JWT ?
|
|
* @param {*} session TODOC
|
|
* @returns
|
|
*/
|
|
function readSession(session) {
|
|
let jwt_parts = session?.split('.');
|
|
|
|
if (jwt_parts?.length === 3) {
|
|
let [header, payload, signature] = jwt_parts;
|
|
header = JSON.parse(utf8Decode(base64Decode(unb64url(header))));
|
|
|
|
if (header.typ === 'JWT' && header.alg === 'HS256') {
|
|
signature = unb64url(signature);
|
|
let id = ssb.getIdentities(':auth');
|
|
|
|
if (id?.length && ssb.hmacsha256verify(id[0], payload, signature)) {
|
|
const result = JSON.parse(utf8Decode(base64Decode(unb64url(payload))));
|
|
const now = new Date().valueOf();
|
|
|
|
if (now < result.exp) {
|
|
print(`JWT valid for another ${(result.exp - now) / 1000} seconds.`);
|
|
return result;
|
|
} else {
|
|
print(`JWT expired by ${(now - result.exp) / 1000} seconds.`);
|
|
}
|
|
} else {
|
|
print('JWT verification failed.');
|
|
}
|
|
} else {
|
|
print('Invalid JWT header.');
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* TODOC
|
|
* @param {*} headers most likely an object
|
|
* @returns
|
|
*/
|
|
function getCookies(headers) {
|
|
let cookies = {};
|
|
|
|
if (headers.cookie) {
|
|
let parts = headers.cookie.split(/,|;/);
|
|
for (let i in parts) {
|
|
let equals = parts[i].indexOf('=');
|
|
let name = parts[i].substring(0, equals).trim();
|
|
let value = parts[i].substring(equals + 1).trim();
|
|
cookies[name] = value;
|
|
}
|
|
}
|
|
|
|
return cookies;
|
|
}
|
|
|
|
/**
|
|
* Gets a user's permissions based on it's session ?
|
|
* @param {*} session TODOC
|
|
* @returns
|
|
*/
|
|
function getPermissions(session) {
|
|
let permissions;
|
|
let entry = readSession(session);
|
|
if (entry) {
|
|
permissions = getPermissionsForUser(entry.name);
|
|
permissions.authenticated = entry.name !== 'guest';
|
|
}
|
|
return permissions || {};
|
|
}
|
|
|
|
/**
|
|
* Get a user's permissions ?
|
|
* @param {string} userName TODOC
|
|
* @returns
|
|
*/
|
|
function getPermissionsForUser(userName) {
|
|
let permissions = {};
|
|
if (
|
|
core.globalSettings &&
|
|
core.globalSettings.permissions &&
|
|
core.globalSettings.permissions[userName]
|
|
) {
|
|
for (let i in core.globalSettings.permissions[userName]) {
|
|
permissions[core.globalSettings.permissions[userName][i]] = true;
|
|
}
|
|
}
|
|
return permissions;
|
|
}
|
|
|
|
/**
|
|
* TODOC
|
|
* @param {*} headers
|
|
* @returns
|
|
*/
|
|
function query(headers) {
|
|
let session = getCookies(headers).session;
|
|
let entry;
|
|
let autologin = tildefriends.args.autologin;
|
|
if ((entry = autologin ? {name: autologin} : readSession(session))) {
|
|
return {
|
|
session: entry,
|
|
permissions: autologin
|
|
? getPermissionsForUser(autologin)
|
|
: getPermissions(session),
|
|
};
|
|
}
|
|
}
|
|
|
|
export {query};
|