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};
 |