mirror of
https://github.com/HeyPuter/puter
synced 2024-11-14 22:06:00 +00:00
dev: allow app tokens to identify user sessions
This commit is contained in:
parent
bc51d4bd52
commit
6b8fbda14c
@ -22,6 +22,7 @@ const { get_user, get_app } = require("../../helpers");
|
||||
const { Context } = require("../../util/context");
|
||||
const APIError = require("../../api/APIError");
|
||||
const { DB_WRITE } = require("../database/consts");
|
||||
const { UUIDFPE } = require("../../util/uuidfpe");
|
||||
|
||||
const APP_ORIGIN_UUID_NAMESPACE = '33de3768-8ee0-43e9-9e73-db192b97a5d8';
|
||||
|
||||
@ -30,6 +31,7 @@ const LegacyTokenError = class extends Error {};
|
||||
class AuthService extends BaseService {
|
||||
static MODULES = {
|
||||
jwt: require('jsonwebtoken'),
|
||||
crypto: require('crypto'),
|
||||
uuidv5: require('uuid').v5,
|
||||
uuidv4: require('uuid').v4,
|
||||
}
|
||||
@ -37,6 +39,11 @@ class AuthService extends BaseService {
|
||||
async _init () {
|
||||
this.db = await this.services.get('database').get(DB_WRITE, 'auth');
|
||||
this.svc_session = await this.services.get('session');
|
||||
|
||||
const uuid_fpe_key = this.config.uuid_fpe_key
|
||||
? UUIDFPE.uuidToBuffer(this.config.uuid_fpe_key)
|
||||
: this.modules.crypto.randomBytes(16);
|
||||
this.uuid_fpe = new UUIDFPE(uuid_fpe_key);
|
||||
|
||||
this.sessions = {};
|
||||
|
||||
@ -78,6 +85,12 @@ class AuthService extends BaseService {
|
||||
}
|
||||
|
||||
if ( decoded.type === 'app-under-user' ) {
|
||||
const session_uuid = this.uuid_fpe.decrypt(decoded.session);
|
||||
const session = await this.get_session_(session_uuid);
|
||||
|
||||
if ( ! session ) {
|
||||
throw APIError.create('token_auth_failed');
|
||||
}
|
||||
const user = await get_user({ uuid: decoded.user_uid });
|
||||
if ( ! user ) {
|
||||
throw APIError.create('token_auth_failed');
|
||||
@ -164,6 +177,7 @@ class AuthService extends BaseService {
|
||||
version: '0.0.0',
|
||||
user_uid: actor_type.user.uuid,
|
||||
app_uid,
|
||||
session: this.uuid_fpe.encrypt(actor_type.session),
|
||||
},
|
||||
this.global_config.jwt_secret,
|
||||
);
|
||||
|
@ -81,6 +81,10 @@ const compression = {
|
||||
short: 'u',
|
||||
...uuid_compression(),
|
||||
},
|
||||
session: {
|
||||
short: 's',
|
||||
...uuid_compression(),
|
||||
},
|
||||
version: 'v',
|
||||
type: {
|
||||
short: 't',
|
||||
|
61
src/backend/src/util/uuidfpe.js
Normal file
61
src/backend/src/util/uuidfpe.js
Normal file
@ -0,0 +1,61 @@
|
||||
const crypto = require('crypto');
|
||||
|
||||
class UUIDFPE {
|
||||
static ALGORITHM = 'aes-128-ecb';
|
||||
|
||||
constructor(key) {
|
||||
if ( !key || key.length !== 16 ) {
|
||||
throw new Error('Key must be a 16-byte Buffer.');
|
||||
}
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
static uuidToBuffer (uuidStr) {
|
||||
const hexStr = uuidStr.replace(/-/g, '');
|
||||
return Buffer.from(hexStr, 'hex');
|
||||
}
|
||||
static bufferToUuid (buffer) {
|
||||
const hexStr = buffer.toString('hex');
|
||||
return [
|
||||
hexStr.substring(0, 8),
|
||||
hexStr.substring(8, 12),
|
||||
hexStr.substring(12, 16),
|
||||
hexStr.substring(16, 20),
|
||||
hexStr.substring(20)
|
||||
].join('-');
|
||||
}
|
||||
|
||||
encrypt(uuidStr) {
|
||||
const plaintext = this.constructor.uuidToBuffer(uuidStr);
|
||||
|
||||
const cipher = crypto.createCipheriv(
|
||||
this.constructor.ALGORITHM,
|
||||
this.key,
|
||||
null,
|
||||
);
|
||||
cipher.setAutoPadding(false);
|
||||
|
||||
const encrypted = Buffer.concat([
|
||||
cipher.update(plaintext),
|
||||
cipher.final(),
|
||||
]);
|
||||
return this.constructor.bufferToUuid(encrypted);
|
||||
}
|
||||
|
||||
decrypt(encryptedUuidStr) {
|
||||
const encrypted = this.constructor.uuidToBuffer(encryptedUuidStr);
|
||||
const decipher = crypto.createDecipheriv(
|
||||
this.constructor.ALGORITHM,
|
||||
this.key,
|
||||
null,
|
||||
);
|
||||
decipher.setAutoPadding(false);
|
||||
|
||||
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
|
||||
return this.constructor.bufferToUuid(decrypted);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
UUIDFPE,
|
||||
};
|
Loading…
Reference in New Issue
Block a user