mirror of
https://github.com/laurent22/joplin.git
synced 2025-01-23 18:53:36 +02:00
Server: Fixed access control on user list and clean up
This commit is contained in:
parent
d2771029a3
commit
20d126b39d
@ -15,8 +15,9 @@ import modelFactory from './models/factory';
|
||||
import controllerFactory from './controllers/factory';
|
||||
import { AppContext, Config, Env } from './utils/types';
|
||||
import FsDriverNode from '@joplin/lib/fs-driver-node';
|
||||
import requestProcessor from './middleware/requestProcessor';
|
||||
import routeHandler from './middleware/routeHandler';
|
||||
import notificationHandler from './middleware/notificationHandler';
|
||||
import ownerHandler from './middleware/ownerHandler';
|
||||
|
||||
const { shimInit } = require('@joplin/lib/shim-init-node.js');
|
||||
shimInit();
|
||||
@ -44,8 +45,13 @@ function appLogger(): LoggerWrapper {
|
||||
|
||||
const app = new Koa();
|
||||
|
||||
// Note: the order of middlewares is important. For example, ownerHandler
|
||||
// loads the user, which is then used by notificationHandler. And finally
|
||||
// routeHandler uses data from both previous middlewares. It would be good to
|
||||
// layout these dependencies in code but not clear how to do this.
|
||||
app.use(ownerHandler);
|
||||
app.use(notificationHandler);
|
||||
app.use(requestProcessor);
|
||||
app.use(routeHandler);
|
||||
|
||||
async function main() {
|
||||
const configObject: Config = configs[env];
|
||||
|
@ -76,7 +76,7 @@ export default class FileController extends BaseController {
|
||||
files.push(await fileToViewItem(file, fileFullPaths));
|
||||
}
|
||||
|
||||
const view: View = defaultView('files', owner);
|
||||
const view: View = defaultView('files');
|
||||
view.content.paginatedFiles = { ...paginatedFiles, items: files };
|
||||
view.content.paginationLinks = paginationLinks;
|
||||
view.content.postUrl = `${baseUrl()}/files`;
|
||||
|
@ -5,8 +5,8 @@ import defaultView from '../../utils/defaultView';
|
||||
export default class HomeController extends BaseController {
|
||||
|
||||
public async getIndex(sessionId: string): Promise<View> {
|
||||
const owner = await this.initSession(sessionId);
|
||||
return defaultView('home', owner);
|
||||
await this.initSession(sessionId);
|
||||
return defaultView('home');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ export default class ProfileController extends BaseController {
|
||||
public async getIndex(sessionId: string, user: User = null, error: any = null): Promise<View> {
|
||||
const owner = await this.initSession(sessionId);
|
||||
|
||||
const view: View = defaultView('profile', owner);
|
||||
const view: View = defaultView('profile');
|
||||
view.content.user = user ? user : owner;
|
||||
view.content.error = error;
|
||||
view.partials.push('errorBanner');
|
||||
|
@ -7,11 +7,11 @@ import { baseUrl } from '../../config';
|
||||
export default class UserController extends BaseController {
|
||||
|
||||
public async getIndex(sessionId: string): Promise<View> {
|
||||
const owner = await this.initSession(sessionId);
|
||||
const owner = await this.initSession(sessionId, true);
|
||||
const userModel = this.models.user({ userId: owner.id });
|
||||
const users = await userModel.all();
|
||||
|
||||
const view: View = defaultView('users', owner);
|
||||
const view: View = defaultView('users');
|
||||
view.content.users = users;
|
||||
return view;
|
||||
}
|
||||
@ -28,7 +28,7 @@ export default class UserController extends BaseController {
|
||||
user = userIdOrString as User;
|
||||
}
|
||||
|
||||
const view: View = defaultView('user', owner);
|
||||
const view: View = defaultView('user');
|
||||
view.content.user = user;
|
||||
view.content.isNew = isNew;
|
||||
view.content.buttonTitle = isNew ? 'Create user' : 'Update profile';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { AppContext, KoaNext, NotificationView } from '../utils/types';
|
||||
import { isApiRequest, contextSessionId } from '../utils/requestUtils';
|
||||
import { defaultAdminEmail, defaultAdminPassword, NotificationLevel, User } from '../db';
|
||||
import { isApiRequest } from '../utils/requestUtils';
|
||||
import { defaultAdminEmail, defaultAdminPassword, NotificationLevel } from '../db';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import Logger from '@joplin/lib/Logger';
|
||||
import * as MarkdownIt from 'markdown-it';
|
||||
@ -13,8 +13,7 @@ export default async function(ctx: AppContext, next: KoaNext): Promise<void> {
|
||||
try {
|
||||
if (isApiRequest(ctx)) return next();
|
||||
|
||||
const sessionId = contextSessionId(ctx);
|
||||
const user: User = await ctx.models.session().sessionUser(sessionId);
|
||||
const user = ctx.owner;
|
||||
if (!user) return next();
|
||||
|
||||
const notificationModel = ctx.models.notification({ userId: user.id });
|
||||
|
17
packages/server/src/middleware/ownerHandler.ts
Normal file
17
packages/server/src/middleware/ownerHandler.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { AppContext, KoaNext } from '../utils/types';
|
||||
import { isApiRequest, contextSessionId } from '../utils/requestUtils';
|
||||
import Logger from '@joplin/lib/Logger';
|
||||
|
||||
const logger = Logger.create('loggedInUserHandler');
|
||||
|
||||
export default async function(ctx: AppContext, next: KoaNext): Promise<void> {
|
||||
try {
|
||||
if (isApiRequest(ctx)) return next();
|
||||
const sessionId = contextSessionId(ctx);
|
||||
ctx.owner = await ctx.models.session().sessionUser(sessionId);
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
}
|
||||
|
||||
return next();
|
||||
}
|
@ -21,6 +21,7 @@ export default async function(ctx: AppContext) {
|
||||
ctx.response.status = 200;
|
||||
ctx.response.body = await mustacheService.renderView(responseObject, {
|
||||
notifications: ctx.notifications || [],
|
||||
owner: ctx.owner,
|
||||
});
|
||||
} else {
|
||||
ctx.response.status = 200;
|
@ -1,14 +1,11 @@
|
||||
import { User } from '../db';
|
||||
import { View } from '../services/MustacheService';
|
||||
|
||||
// Populate a View object with some good defaults.
|
||||
export default function(name: string, owner: User = null): View {
|
||||
export default function(name: string): View {
|
||||
return {
|
||||
name: name,
|
||||
path: `index/${name}`,
|
||||
content: {
|
||||
owner,
|
||||
},
|
||||
content: {},
|
||||
partials: [
|
||||
'navbar',
|
||||
'notifications',
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { LoggerWrapper } from '@joplin/lib/Logger';
|
||||
import * as Koa from 'koa';
|
||||
import { Controllers } from '../controllers/factory';
|
||||
import { DbConnection, Uuid } from '../db';
|
||||
import { DbConnection, User, Uuid } from '../db';
|
||||
import { Models } from '../models/factory';
|
||||
|
||||
export enum Env {
|
||||
@ -24,6 +24,7 @@ export interface AppContext extends Koa.Context {
|
||||
controllers: Controllers;
|
||||
appLogger(): LoggerWrapper;
|
||||
notifications: NotificationView[];
|
||||
owner: User;
|
||||
}
|
||||
|
||||
export interface DatabaseConfig {
|
||||
|
@ -1,6 +1 @@
|
||||
Welcome {{owner.email}}
|
||||
|
||||
|
||||
<ul>
|
||||
|
||||
</ul>
|
||||
Welcome {{global.owner.email}}
|
@ -7,11 +7,13 @@
|
||||
<div class="navbar-menu is-active">
|
||||
<div class="navbar-start">
|
||||
<a class="navbar-item" href="{{{global.baseUrl}}}/home">Home</a>
|
||||
<a class="navbar-item" href="{{{global.baseUrl}}}/users">Users</a>
|
||||
{{#global.owner.is_admin}}
|
||||
<a class="navbar-item" href="{{{global.baseUrl}}}/users">Users</a>
|
||||
{{/global.owner.is_admin}}
|
||||
<a class="navbar-item" href="{{{global.baseUrl}}}/files">Files</a>
|
||||
</div>
|
||||
<div class="navbar-end">
|
||||
<div class="navbar-item">{{owner.email}}</div>
|
||||
<div class="navbar-item">{{global.owner.email}}</div>
|
||||
<a class="navbar-item" href="{{{global.baseUrl}}}/profile">Profile</a>
|
||||
<div class="navbar-item">
|
||||
<form method="post" action="{{{global.baseUrl}}}/logout">
|
||||
|
Loading…
x
Reference in New Issue
Block a user