Fixed session swap handling on server

pull/5493/head
Laurent Cozic 2021-09-21 12:31:53 +01:00
parent 7fac1941cd
commit a7eea9fc21
2 changed files with 15 additions and 12 deletions

View File

@ -2,7 +2,7 @@ import { SubPath, redirect } from '../../utils/routeUtils';
import Router from '../../utils/Router';
import { RouteType } from '../../utils/types';
import { AppContext, HttpMethod } from '../../utils/types';
import { bodyFields, contextSessionId, formParse } from '../../utils/requestUtils';
import { bodyFields, formParse } from '../../utils/requestUtils';
import { ErrorForbidden, ErrorUnprocessableEntity } from '../../utils/errors';
import { User, UserFlagType, userFlagTypeToLabel, Uuid } from '../../services/database/types';
import config from '../../config';
@ -291,7 +291,7 @@ interface FormFields {
send_account_confirmation_email: string;
update_subscription_basic_button: string;
update_subscription_pro_button: string;
user_cancel_subscription_button: string;
// user_cancel_subscription_button: string;
impersonate_button: string;
stop_impersonate_button: string;
}
@ -324,13 +324,13 @@ router.post('users', async (path: SubPath, ctx: AppContext) => {
await models.user().save(userToSave, { isNew: false });
}
} else if (fields.user_cancel_subscription_button) {
await cancelSubscriptionByUserId(models, userId);
const sessionId = contextSessionId(ctx, false);
if (sessionId) {
await models.session().logout(sessionId);
return redirect(ctx, config().baseUrl);
}
// } else if (fields.user_cancel_subscription_button) {
// await cancelSubscriptionByUserId(models, userId);
// const sessionId = contextSessionId(ctx, false);
// if (sessionId) {
// await models.session().logout(sessionId);
// return redirect(ctx, config().baseUrl);
// }
} else if (fields.stop_impersonate_button) {
await stopImpersonating(ctx);
return redirect(ctx, config().baseUrl);

View File

@ -11,6 +11,7 @@ export function getImpersonatorAdminSessionId(ctx: AppContext): string {
export async function startImpersonating(ctx: AppContext, userId: Uuid) {
const adminSessionId = contextSessionId(ctx);
const user = await ctx.joplin.models.session().sessionUser(adminSessionId);
if (!user) throw new Error(`No user for session: ${adminSessionId}`);
if (!user.is_admin) throw new ErrorForbidden('Impersonator must be an admin');
const impersonatedSession = await ctx.joplin.models.session().createUserSession(userId);
@ -22,9 +23,11 @@ export async function stopImpersonating(ctx: AppContext) {
const adminSessionId = cookieGet(ctx, 'adminSessionId');
if (!adminSessionId) throw new Error('Missing cookie adminSessionId');
const adminUser = await ctx.joplin.models.session().sessionUser(adminSessionId);
if (!adminUser.is_admin) throw new ErrorForbidden('User must be an admin');
// This function simply moves the adminSessionId back to sessionId. There's
// no need to check if anything is valid because that will be done by other
// session checking routines. We also don't want this function to fail
// because it would leave the cookies in an invalid state (for example if
// the admin has lost their sessions, or the user no longer exists).
cookieDelete(ctx, 'adminSessionId');
cookieSet(ctx, 'sessionId', adminSessionId);
}