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;
|
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;
|
module.exports = config;
|
||||||
|
|
||||||
// NEW_CONFIG_LOADING
|
// NEW_CONFIG_LOADING
|
||||||
|
@ -18,8 +18,24 @@
|
|||||||
*/
|
*/
|
||||||
const APIError = require("../api/APIError");
|
const APIError = require("../api/APIError");
|
||||||
const config = require("../config");
|
const config = require("../config");
|
||||||
|
const { UserActorType } = require("../services/auth/Actor");
|
||||||
|
const { LegacyTokenError } = require("../services/auth/AuthService");
|
||||||
const { Context } = require("../util/context");
|
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
|
// TODO: Allow auth middleware to be used without requiring
|
||||||
// authentication. This will allow us to use the auth middleware
|
// authentication. This will allow us to use the auth middleware
|
||||||
// in endpoints that do not require authentication, but can
|
// in endpoints that do not require authentication, but can
|
||||||
@ -70,6 +86,20 @@ const auth2 = async (req, res, next) => {
|
|||||||
e.write(res);
|
e.write(res);
|
||||||
return;
|
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');
|
const re = APIError.create('token_auth_failed');
|
||||||
re.write(res);
|
re.write(res);
|
||||||
return;
|
return;
|
||||||
|
@ -54,6 +54,7 @@ const WHOAMI_GET = eggspress('/whoami', {
|
|||||||
is_temp: (req.user.password === null && req.user.email === null),
|
is_temp: (req.user.password === null && req.user.email === null),
|
||||||
taskbar_items: await get_taskbar_items(req.user),
|
taskbar_items: await get_taskbar_items(req.user),
|
||||||
referral_code: req.user.referral_code,
|
referral_code: req.user.referral_code,
|
||||||
|
...(req.new_token ? { token: req.token } : {})
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( ! is_user ) {
|
if ( ! is_user ) {
|
||||||
@ -65,6 +66,7 @@ const WHOAMI_GET = eggspress('/whoami', {
|
|||||||
delete details.desktop_bg_color;
|
delete details.desktop_bg_color;
|
||||||
delete details.desktop_bg_fit;
|
delete details.desktop_bg_fit;
|
||||||
delete details.taskbar_items;
|
delete details.taskbar_items;
|
||||||
|
delete details.token;
|
||||||
}
|
}
|
||||||
|
|
||||||
res.send(details);
|
res.send(details);
|
||||||
@ -76,8 +78,19 @@ const WHOAMI_GET = eggspress('/whoami', {
|
|||||||
const WHOAMI_POST = new express.Router();
|
const WHOAMI_POST = new express.Router();
|
||||||
WHOAMI_POST.post('/whoami', auth, fs, express.json(), async (req, response, next)=>{
|
WHOAMI_POST.post('/whoami', auth, fs, express.json(), async (req, response, next)=>{
|
||||||
// check subdomain
|
// check subdomain
|
||||||
if(require('../helpers').subdomain(req) !== 'api')
|
if(require('../helpers').subdomain(req) !== 'api') {
|
||||||
next();
|
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 = [];
|
let desktop_items = [];
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@ const { DB_WRITE } = require("../database/consts");
|
|||||||
|
|
||||||
const APP_ORIGIN_UUID_NAMESPACE = '33de3768-8ee0-43e9-9e73-db192b97a5d8';
|
const APP_ORIGIN_UUID_NAMESPACE = '33de3768-8ee0-43e9-9e73-db192b97a5d8';
|
||||||
|
|
||||||
|
const LegacyTokenError = class extends Error {};
|
||||||
|
|
||||||
class AuthService extends BaseService {
|
class AuthService extends BaseService {
|
||||||
static MODULES = {
|
static MODULES = {
|
||||||
jwt: require('jsonwebtoken'),
|
jwt: require('jsonwebtoken'),
|
||||||
@ -45,7 +47,7 @@ class AuthService extends BaseService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if ( ! decoded.hasOwnProperty('type') ) {
|
if ( ! decoded.hasOwnProperty('type') ) {
|
||||||
throw new Error('legacy token');
|
throw new LegacyTokenError();
|
||||||
const user = await this.db.requireRead(
|
const user = await this.db.requireRead(
|
||||||
"SELECT * FROM `user` WHERE `uuid` = ? LIMIT 1",
|
"SELECT * FROM `user` WHERE `uuid` = ? LIMIT 1",
|
||||||
[decoded.uuid],
|
[decoded.uuid],
|
||||||
@ -251,7 +253,7 @@ class AuthService extends BaseService {
|
|||||||
user_uid: user.uuid,
|
user_uid: user.uuid,
|
||||||
}, this.global_config.jwt_secret);
|
}, this.global_config.jwt_secret);
|
||||||
|
|
||||||
return token;
|
return { session, token };
|
||||||
}
|
}
|
||||||
|
|
||||||
async check_session (cur_token, meta) {
|
async check_session (cur_token, meta) {
|
||||||
@ -265,12 +267,16 @@ class AuthService extends BaseService {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await get_user({ uuid: decoded.user_uid });
|
const is_legacy = ! decoded.type;
|
||||||
|
|
||||||
|
const user = await get_user({ uuid:
|
||||||
|
is_legacy ? decoded.uuid : decoded.user_uid
|
||||||
|
});
|
||||||
if ( ! user ) {
|
if ( ! user ) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( decoded.type ) {
|
if ( ! is_legacy ) {
|
||||||
// Ensure session exists
|
// Ensure session exists
|
||||||
const session = await this.get_session_(decoded.uuid);
|
const session = await this.get_session_(decoded.uuid);
|
||||||
if ( ! session ) {
|
if ( ! session ) {
|
||||||
@ -285,8 +291,19 @@ class AuthService extends BaseService {
|
|||||||
|
|
||||||
// Upgrade legacy token
|
// Upgrade legacy token
|
||||||
// TODO: phase this out
|
// TODO: phase this out
|
||||||
const { token } = await this.create_session_token(user, meta);
|
const { session, token } = await this.create_session_token(user, meta);
|
||||||
return { user, token };
|
|
||||||
|
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) {
|
async create_access_token (authorizer, permissions) {
|
||||||
@ -430,4 +447,5 @@ class AuthService extends BaseService {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
AuthService,
|
AuthService,
|
||||||
|
LegacyTokenError,
|
||||||
};
|
};
|
||||||
|
@ -366,7 +366,7 @@ window.initgui = async function(){
|
|||||||
}
|
}
|
||||||
while(!is_verified)
|
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
|
// Load desktop, only if we're not embedded in a popup
|
||||||
|
Loading…
Reference in New Issue
Block a user