mirror of
https://github.com/HeyPuter/puter
synced 2024-11-15 06:15:47 +00:00
Add automatic token migration
This commit is contained in:
parent
09bf422686
commit
bb9edc4f65
@ -97,6 +97,10 @@ if (config.server_id) {
|
||||
|
||||
config.contact_email = 'hey@' + config.domain;
|
||||
|
||||
// TODO: default value will be changed to false in a future release;
|
||||
// details to follow in a future announcement.
|
||||
config.legacy_token_migrate = true;
|
||||
|
||||
module.exports = config;
|
||||
|
||||
// NEW_CONFIG_LOADING
|
||||
|
@ -18,8 +18,24 @@
|
||||
*/
|
||||
const APIError = require("../api/APIError");
|
||||
const config = require("../config");
|
||||
const { UserActorType } = require("../services/auth/Actor");
|
||||
const { LegacyTokenError } = require("../services/auth/AuthService");
|
||||
const { Context } = require("../util/context");
|
||||
|
||||
// The "/whoami" endpoint is a special case where we want to allow
|
||||
// a legacy token to be used for authentication. The "/whoami"
|
||||
// endpoint will then return a new token for further requests.
|
||||
//
|
||||
const is_whoami = (req) => {
|
||||
if ( ! config.legacy_token_migrate ) return;
|
||||
|
||||
if ( req.path !== '/whoami' ) return;
|
||||
|
||||
// const subdomain = req.subdomains[res.subdomains.length - 1];
|
||||
// if ( subdomain !== 'api' ) return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: Allow auth middleware to be used without requiring
|
||||
// authentication. This will allow us to use the auth middleware
|
||||
// in endpoints that do not require authentication, but can
|
||||
@ -70,6 +86,20 @@ const auth2 = async (req, res, next) => {
|
||||
e.write(res);
|
||||
return;
|
||||
}
|
||||
if ( e instanceof LegacyTokenError && is_whoami(req) ) {
|
||||
const new_info = await svc_auth.check_session(token, {
|
||||
req,
|
||||
from_upgrade: true,
|
||||
})
|
||||
context.set('actor', new_info.actor);
|
||||
context.set('user', new_info.user);
|
||||
req.new_token = new_info.token;
|
||||
req.token = new_info.token;
|
||||
req.user = new_info.user;
|
||||
req.actor = new_info.actor;
|
||||
next();
|
||||
return;
|
||||
}
|
||||
const re = APIError.create('token_auth_failed');
|
||||
re.write(res);
|
||||
return;
|
||||
|
@ -54,6 +54,7 @@ const WHOAMI_GET = eggspress('/whoami', {
|
||||
is_temp: (req.user.password === null && req.user.email === null),
|
||||
taskbar_items: await get_taskbar_items(req.user),
|
||||
referral_code: req.user.referral_code,
|
||||
...(req.new_token ? { token: req.token } : {})
|
||||
};
|
||||
|
||||
if ( ! is_user ) {
|
||||
@ -65,6 +66,7 @@ const WHOAMI_GET = eggspress('/whoami', {
|
||||
delete details.desktop_bg_color;
|
||||
delete details.desktop_bg_fit;
|
||||
delete details.taskbar_items;
|
||||
delete details.token;
|
||||
}
|
||||
|
||||
res.send(details);
|
||||
@ -76,8 +78,19 @@ const WHOAMI_GET = eggspress('/whoami', {
|
||||
const WHOAMI_POST = new express.Router();
|
||||
WHOAMI_POST.post('/whoami', auth, fs, express.json(), async (req, response, next)=>{
|
||||
// check subdomain
|
||||
if(require('../helpers').subdomain(req) !== 'api')
|
||||
next();
|
||||
if(require('../helpers').subdomain(req) !== 'api') {
|
||||
return;
|
||||
}
|
||||
|
||||
const actor = Context.get('actor');
|
||||
if ( ! actor ) {
|
||||
throw Error('actor not found in context');
|
||||
}
|
||||
|
||||
const is_user = actor.type instanceof UserActorType;
|
||||
if ( ! is_user ) {
|
||||
throw Error('actor is not a user');
|
||||
}
|
||||
|
||||
let desktop_items = [];
|
||||
|
||||
|
@ -25,6 +25,8 @@ const { DB_WRITE } = require("../database/consts");
|
||||
|
||||
const APP_ORIGIN_UUID_NAMESPACE = '33de3768-8ee0-43e9-9e73-db192b97a5d8';
|
||||
|
||||
const LegacyTokenError = class extends Error {};
|
||||
|
||||
class AuthService extends BaseService {
|
||||
static MODULES = {
|
||||
jwt: require('jsonwebtoken'),
|
||||
@ -45,7 +47,7 @@ class AuthService extends BaseService {
|
||||
);
|
||||
|
||||
if ( ! decoded.hasOwnProperty('type') ) {
|
||||
throw new Error('legacy token');
|
||||
throw new LegacyTokenError();
|
||||
const user = await this.db.requireRead(
|
||||
"SELECT * FROM `user` WHERE `uuid` = ? LIMIT 1",
|
||||
[decoded.uuid],
|
||||
@ -251,7 +253,7 @@ class AuthService extends BaseService {
|
||||
user_uid: user.uuid,
|
||||
}, this.global_config.jwt_secret);
|
||||
|
||||
return token;
|
||||
return { session, token };
|
||||
}
|
||||
|
||||
async check_session (cur_token, meta) {
|
||||
@ -264,13 +266,17 @@ class AuthService extends BaseService {
|
||||
if ( decoded.type && decoded.type !== 'session' ) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const is_legacy = ! decoded.type;
|
||||
|
||||
const user = await get_user({ uuid: decoded.user_uid });
|
||||
const user = await get_user({ uuid:
|
||||
is_legacy ? decoded.uuid : decoded.user_uid
|
||||
});
|
||||
if ( ! user ) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if ( decoded.type ) {
|
||||
if ( ! is_legacy ) {
|
||||
// Ensure session exists
|
||||
const session = await this.get_session_(decoded.uuid);
|
||||
if ( ! session ) {
|
||||
@ -285,8 +291,19 @@ class AuthService extends BaseService {
|
||||
|
||||
// Upgrade legacy token
|
||||
// TODO: phase this out
|
||||
const { token } = await this.create_session_token(user, meta);
|
||||
return { user, token };
|
||||
const { session, token } = await this.create_session_token(user, meta);
|
||||
|
||||
const actor_type = new UserActorType({
|
||||
user,
|
||||
session,
|
||||
});
|
||||
|
||||
const actor = new Actor({
|
||||
user_uid: user.uuid,
|
||||
type: actor_type,
|
||||
});
|
||||
|
||||
return { actor, user, token };
|
||||
}
|
||||
|
||||
async create_access_token (authorizer, permissions) {
|
||||
@ -430,4 +447,5 @@ class AuthService extends BaseService {
|
||||
|
||||
module.exports = {
|
||||
AuthService,
|
||||
LegacyTokenError,
|
||||
};
|
||||
|
@ -366,7 +366,7 @@ window.initgui = async function(){
|
||||
}
|
||||
while(!is_verified)
|
||||
}
|
||||
update_auth_data(window.auth_token, whoami);
|
||||
update_auth_data(whoami.token || window.auth_token, whoami);
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
// Load desktop, only if we're not embedded in a popup
|
||||
|
Loading…
Reference in New Issue
Block a user