mirror of
https://github.com/HeyPuter/puter.git
synced 2026-05-04 08:30:39 +00:00
dev(backend): add revoke_access_token endpoint
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2024-present Puter Technologies Inc.
|
||||
*
|
||||
* This file is part of Puter.
|
||||
*
|
||||
* Puter is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const APIError = require('../../api/APIError');
|
||||
const eggspress = require('../../api/eggspress');
|
||||
const { Context } = require('../../util/context');
|
||||
|
||||
/**
|
||||
* Coerces a read-URL string to the token (JWT) from its query.
|
||||
* Works for absolute or relative URLs (e.g. .../token-read?uid=...&token=...).
|
||||
* Returns the given value unchanged if it does not look like a read URL.
|
||||
*/
|
||||
function tokenOrUuidFromInput (value) {
|
||||
if ( typeof value !== 'string' || !value.trim() ) {
|
||||
return value;
|
||||
}
|
||||
const s = value.trim();
|
||||
console.log('s?', s);
|
||||
if ( s.includes('/token-read') ) {
|
||||
try {
|
||||
const url = new URL(s);
|
||||
const token = url.searchParams.get('token');
|
||||
console.log('token?', token);
|
||||
return token ?? s;
|
||||
} catch (_) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
module.exports = eggspress('/auth/revoke-access-token', {
|
||||
subdomain: 'api',
|
||||
auth2: true,
|
||||
allowedMethods: ['POST'],
|
||||
}, async (req, res, next) => {
|
||||
const x = Context.get();
|
||||
const svc_auth = x.get('services').get('auth');
|
||||
|
||||
const raw = req.body.tokenOrUuid;
|
||||
if ( raw === undefined || raw === null ) {
|
||||
throw APIError.create('field_missing', null, { key: 'tokenOrUuid' });
|
||||
}
|
||||
const tokenOrUuid = tokenOrUuidFromInput(raw);
|
||||
|
||||
await svc_auth.revoke_access_token(tokenOrUuid);
|
||||
|
||||
res.json({ ok: true });
|
||||
});
|
||||
@@ -50,6 +50,7 @@ class PuterAPIService extends BaseService {
|
||||
app.use(require('../routers/auth/check-app'));
|
||||
app.use(require('../routers/auth/app-uid-from-origin'));
|
||||
app.use(require('../routers/auth/create-access-token'));
|
||||
app.use(require('../routers/auth/revoke-access-token'));
|
||||
app.use(require('../routers/auth/delete-own-user'));
|
||||
app.use(require('../routers/auth/configure-2fa'));
|
||||
app.use(require('../routers/drivers/call'));
|
||||
|
||||
@@ -444,9 +444,39 @@ class AuthService extends BaseService {
|
||||
Object.values(insert_object));
|
||||
}
|
||||
|
||||
console.log('token uuid?', uuid);
|
||||
|
||||
return jwt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Revokes an access token by removing it from the database.
|
||||
* Accepts either the access token JWT or the token UUID.
|
||||
*
|
||||
* @param {string} tokenOrUuid - The access token JWT or the token UUID.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async revoke_access_token (tokenOrUuid) {
|
||||
let token_uid;
|
||||
const isJwt = typeof tokenOrUuid === 'string' &&
|
||||
/^[\w-]*\.[\w-]*\.[\w-]*$/.test(tokenOrUuid.trim());
|
||||
if ( isJwt ) {
|
||||
const decoded = this.modules.jwt.verify(tokenOrUuid, this.global_config.jwt_secret);
|
||||
if ( decoded.type !== 'access-token' || !decoded.token_uid ) {
|
||||
throw APIError.create('token_auth_failed');
|
||||
}
|
||||
token_uid = decoded.token_uid;
|
||||
} else {
|
||||
token_uid = tokenOrUuid;
|
||||
}
|
||||
/* eslint-disable */
|
||||
await this.db.write(
|
||||
'DELETE FROM `access_token_permissions` WHERE `token_uid` = ?',
|
||||
[token_uid],
|
||||
);
|
||||
/* eslint-enable */
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the session list for the specified actor.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user