5htp-core 0.5.9 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/app/component.tsx +1 -0
- package/client/assets/css/colors.less +244 -0
- package/client/assets/css/components/button.less +27 -9
- package/client/assets/css/components/card.less +24 -0
- package/client/assets/css/components/input.less +0 -4
- package/client/assets/css/components/mantine.less +11 -0
- package/client/assets/css/components/other.less +1 -0
- package/client/assets/css/components/progressbar.less +45 -0
- package/client/assets/css/components/table.less +8 -12
- package/client/assets/css/components.less +1 -0
- package/client/assets/css/core.less +6 -4
- package/client/assets/css/text/text.less +0 -9
- package/client/assets/css/theme.less +10 -0
- package/client/assets/css/utils/layouts.less +8 -4
- package/client/assets/css/utils/sizing.less +2 -0
- package/client/components/Card/index.tsx +1 -2
- package/client/components/Checkbox.tsx +2 -1
- package/client/components/DropDown.tsx +11 -5
- package/client/components/Input.tsx +1 -0
- package/client/components/Rte/ToolbarPlugin/BlockFormat.tsx +1 -1
- package/client/components/Rte/ToolbarPlugin/ElementFormat.tsx +5 -3
- package/client/components/Rte/ToolbarPlugin/index.tsx +4 -4
- package/client/components/Select.tsx +95 -69
- package/client/components/Table/index.tsx +34 -23
- package/client/components/containers/Popover/index.tsx +1 -1
- package/client/components/containers/Popover/popover.less +1 -1
- package/client/components/index.ts +3 -2
- package/client/components/utils.tsx +5 -5
- package/client/index.ts +1 -0
- package/client/services/router/components/router.tsx +0 -1
- package/client/services/router/index.tsx +1 -2
- package/client/services/router/request/api.ts +4 -4
- package/common/errors/index.tsx +6 -0
- package/common/router/index.ts +8 -2
- package/package.json +1 -2
- package/server/app/commands.ts +2 -21
- package/server/app/container/console/index.ts +1 -6
- package/server/app/container/index.ts +0 -2
- package/server/app/index.ts +88 -22
- package/server/app/service/index.ts +30 -35
- package/server/services/auth/index.ts +15 -17
- package/server/services/auth/old.ts +1 -1
- package/server/services/auth/router/index.ts +24 -12
- package/server/services/cache/index.ts +5 -16
- package/server/services/cron/index.ts +2 -9
- package/server/services/database/index.ts +5 -10
- package/server/services/database/stats.ts +0 -2
- package/server/services/disks/driver.ts +1 -1
- package/server/services/disks/drivers/s3/index.ts +4 -8
- package/server/services/disks/index.ts +10 -9
- package/server/services/email/index.ts +5 -2
- package/server/services/email/transporter.ts +1 -21
- package/server/services/fetch/index.ts +9 -11
- package/server/services/fetch/service.json +2 -1
- package/server/services/prisma/index.ts +1 -14
- package/server/services/router/index.ts +28 -53
- package/server/services/router/request/api.ts +2 -7
- package/server/services/router/service.ts +5 -17
- package/server/services/security/encrypt/aes/index.ts +1 -1
- package/server/services/socket/index.ts +11 -19
- package/types/global/utils.d.ts +44 -1
- package/types/icons.d.ts +1 -1
- package/server/app/container/patch.ts +0 -15
|
@@ -206,11 +206,6 @@ export default class Console {
|
|
|
206
206
|
this.enableLogging(origLog);
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
-
// Avoid to use lifecycle functions
|
|
210
|
-
protected async start() {}
|
|
211
|
-
public async ready() {}
|
|
212
|
-
public async shutdown() {}
|
|
213
|
-
|
|
214
209
|
private enableLogging( origLog: typeof console.log ) {
|
|
215
210
|
|
|
216
211
|
const minLogLevel = logLevels[this.config.level];
|
|
@@ -381,7 +376,7 @@ export default class Console {
|
|
|
381
376
|
logs
|
|
382
377
|
}
|
|
383
378
|
|
|
384
|
-
await application.
|
|
379
|
+
await application.runHook('bug', bugReport);
|
|
385
380
|
}
|
|
386
381
|
|
|
387
382
|
public getChannel() {
|
package/server/app/index.ts
CHANGED
|
@@ -7,16 +7,16 @@ import type express from 'express';
|
|
|
7
7
|
|
|
8
8
|
// Core
|
|
9
9
|
import AppContainer from './container';
|
|
10
|
-
import ApplicationService, { StartedServicesIndex } from './service';
|
|
10
|
+
import ApplicationService, { AnyService, StartedServicesIndex } from './service';
|
|
11
11
|
import CommandsManager from './commands';
|
|
12
12
|
import ServicesContainer, {
|
|
13
13
|
ServicesContainer as ServicesContainerClass,
|
|
14
14
|
TServiceMetas
|
|
15
15
|
} from './service/container';
|
|
16
|
-
import type { ServerBug } from './container/console';
|
|
17
16
|
|
|
18
17
|
// Built-in
|
|
19
|
-
import type { default as Router, Request as ServerRequest } from '@server/services/router';
|
|
18
|
+
import type { default as Router, Request as ServerRequest, TRoute } from '@server/services/router';
|
|
19
|
+
import { Anomaly } from '@common/errors';
|
|
20
20
|
|
|
21
21
|
export { default as Services } from './service/container';
|
|
22
22
|
export type { TEnvConfig as Environment } from './container/config';
|
|
@@ -55,7 +55,7 @@ export type ApplicationProperties = Prettify<keyof Application>;
|
|
|
55
55
|
----------------------------------*/
|
|
56
56
|
export abstract class Application<
|
|
57
57
|
TServicesContainer extends ServicesContainerClass = ServicesContainerClass
|
|
58
|
-
> extends ApplicationService<Config, Hooks,
|
|
58
|
+
> extends ApplicationService<Config, Hooks, Application> {
|
|
59
59
|
|
|
60
60
|
public app!: this;
|
|
61
61
|
public servicesContainer!: TServicesContainer;
|
|
@@ -81,9 +81,13 @@ export abstract class Application<
|
|
|
81
81
|
// Status
|
|
82
82
|
public debug: boolean = false;
|
|
83
83
|
public launched: boolean = false;
|
|
84
|
-
|
|
85
|
-
protected abstract
|
|
86
|
-
|
|
84
|
+
|
|
85
|
+
protected abstract registered: {
|
|
86
|
+
[serviceId: string]: {
|
|
87
|
+
name: string,
|
|
88
|
+
start: () => AnyService
|
|
89
|
+
}
|
|
90
|
+
};
|
|
87
91
|
|
|
88
92
|
/*----------------------------------
|
|
89
93
|
- INIT
|
|
@@ -95,7 +99,7 @@ export abstract class Application<
|
|
|
95
99
|
|
|
96
100
|
// Application itself doesnt have configuration
|
|
97
101
|
// Configuration must be handled by application services
|
|
98
|
-
super(self, {},
|
|
102
|
+
super(self, {}, self);
|
|
99
103
|
|
|
100
104
|
// Handle unhandled crash
|
|
101
105
|
this.on('error', (e, request) => this.container.handleBug(e, "An error occured in the application", request));
|
|
@@ -109,7 +113,13 @@ export abstract class Application<
|
|
|
109
113
|
// We can't pass this in super so we assign here
|
|
110
114
|
this.parent = this;
|
|
111
115
|
this.app = this;
|
|
112
|
-
|
|
116
|
+
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public report(...anomalyArgs: ConstructorParameters<typeof Anomaly>) {
|
|
120
|
+
return this.container.Console.createBugReport(
|
|
121
|
+
new Anomaly(...anomalyArgs)
|
|
122
|
+
);
|
|
113
123
|
}
|
|
114
124
|
|
|
115
125
|
/*----------------------------------
|
|
@@ -132,6 +142,11 @@ export abstract class Application<
|
|
|
132
142
|
console.log("Core version", CORE_VERSION);
|
|
133
143
|
const startTime = Date.now();
|
|
134
144
|
|
|
145
|
+
this.startServices();
|
|
146
|
+
|
|
147
|
+
console.log('----------------------------------');
|
|
148
|
+
console.log('- SERVICES');
|
|
149
|
+
console.log('----------------------------------');
|
|
135
150
|
await this.ready();
|
|
136
151
|
await this.runHook('ready');
|
|
137
152
|
|
|
@@ -144,33 +159,54 @@ export abstract class Application<
|
|
|
144
159
|
- ERROR HANDLING
|
|
145
160
|
----------------------------------*/
|
|
146
161
|
|
|
147
|
-
|
|
148
|
-
|
|
162
|
+
private startServices() {
|
|
163
|
+
|
|
164
|
+
// Satrt services
|
|
165
|
+
for (const serviceId in this.registered) {
|
|
166
|
+
try {
|
|
167
|
+
const service = this.registered[serviceId];
|
|
168
|
+
const instance = service.start();
|
|
169
|
+
this[service.name] = instance.getServiceInstance();
|
|
170
|
+
} catch (error) {
|
|
171
|
+
console.error("Error while starting service", serviceId, error);
|
|
172
|
+
throw error;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public register( service: AnyService ) {
|
|
149
178
|
|
|
150
|
-
|
|
179
|
+
service.ready();
|
|
151
180
|
|
|
152
181
|
}
|
|
153
182
|
|
|
154
183
|
protected async ready() {
|
|
155
184
|
|
|
156
|
-
|
|
157
|
-
|
|
185
|
+
// Print services
|
|
186
|
+
const processService = async (propKey: string, service: AnyService, level: number = 0) => {
|
|
158
187
|
|
|
159
|
-
|
|
188
|
+
if (service.status !== 'starting')
|
|
189
|
+
return;
|
|
160
190
|
|
|
161
|
-
|
|
162
|
-
|
|
191
|
+
// Services start shouldn't block app boot
|
|
192
|
+
// use await ServiceName.started to make services depends on each other
|
|
193
|
+
this.starting = service.ready();
|
|
194
|
+
service.status = 'running';
|
|
195
|
+
console.log('-' + '-'.repeat(level * 1), propKey + ': ' + service.constructor.name);
|
|
163
196
|
|
|
164
|
-
|
|
197
|
+
// Routes
|
|
198
|
+
const routes = service.__routes as TRoute[];
|
|
165
199
|
if (routes) for (const route of routes) {
|
|
166
200
|
|
|
201
|
+
console.log('Attached service', service.constructor.name, 'to route', route.path);
|
|
202
|
+
|
|
167
203
|
const origController = route.controller;
|
|
168
204
|
route.controller = (context: RouterContext) => {
|
|
169
205
|
|
|
170
206
|
// Filter data
|
|
171
|
-
const data = route.
|
|
172
|
-
? route.
|
|
173
|
-
:
|
|
207
|
+
const data = route.schema
|
|
208
|
+
? route.schema.parse( context.request.data )
|
|
209
|
+
: {};
|
|
174
210
|
|
|
175
211
|
// Run controller
|
|
176
212
|
return origController.bind( service )(
|
|
@@ -181,8 +217,38 @@ export abstract class Application<
|
|
|
181
217
|
|
|
182
218
|
this.Router.controllers[ route.path ] = route;
|
|
183
219
|
}
|
|
220
|
+
|
|
221
|
+
// Subservices
|
|
222
|
+
for (const propKey in service) {
|
|
223
|
+
|
|
224
|
+
if (propKey === 'app')
|
|
225
|
+
continue;
|
|
226
|
+
const propValue = service[propKey];
|
|
227
|
+
|
|
228
|
+
// Check if service
|
|
229
|
+
const isService =
|
|
230
|
+
typeof propValue === 'object' &&
|
|
231
|
+
!(propValue instanceof Application) &&
|
|
232
|
+
propValue !== null &&
|
|
233
|
+
propValue.status !== undefined;
|
|
234
|
+
if (!isService)
|
|
235
|
+
continue;
|
|
236
|
+
|
|
237
|
+
// Services start shouldn't block app boot
|
|
238
|
+
processService(propKey, propValue, level + 1);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
for (const serviceId in this.registered) {
|
|
243
|
+
|
|
244
|
+
const registeredService = this.registered[serviceId];
|
|
245
|
+
const service = this[registeredService.name];
|
|
184
246
|
|
|
185
|
-
|
|
247
|
+
// TODO: move to router
|
|
248
|
+
// Application.on('service.ready')
|
|
249
|
+
|
|
250
|
+
// Services start shouldn't block app boot
|
|
251
|
+
processService(serviceId, service);
|
|
186
252
|
}
|
|
187
253
|
}
|
|
188
254
|
|
|
@@ -7,17 +7,16 @@ import type { Application } from "..";
|
|
|
7
7
|
import type { Command } from "../commands";
|
|
8
8
|
import type { TServiceMetas } from './container';
|
|
9
9
|
import type { TControllerDefinition, TRoute } from '../../services/router';
|
|
10
|
+
import { Anomaly } from "@common/errors";
|
|
11
|
+
|
|
12
|
+
export { default as schema } from 'zod';
|
|
10
13
|
|
|
11
14
|
/*----------------------------------
|
|
12
15
|
- TYPES: OPTIONS
|
|
13
16
|
----------------------------------*/
|
|
14
17
|
|
|
15
18
|
export type AnyService<TSubServices extends StartedServicesIndex = StartedServicesIndex> =
|
|
16
|
-
Service<{}, {}, Application
|
|
17
|
-
|
|
18
|
-
type TServiceConfig = {
|
|
19
|
-
priority?: number
|
|
20
|
-
}
|
|
19
|
+
Service<{}, {}, Application>
|
|
21
20
|
|
|
22
21
|
export type { TRegisteredServicesIndex, TRegisteredService } from './container';
|
|
23
22
|
|
|
@@ -41,9 +40,11 @@ export type StartedServicesIndex = {
|
|
|
41
40
|
[serviceId: string]: AnyService
|
|
42
41
|
}
|
|
43
42
|
|
|
44
|
-
type
|
|
45
|
-
|
|
46
|
-
}
|
|
43
|
+
export type TServiceArgs<TService extends AnyService> = [
|
|
44
|
+
parent: AnyService | 'self',
|
|
45
|
+
getConfig: (instance: TService) => {},
|
|
46
|
+
app: TService['app'] | 'self'
|
|
47
|
+
]
|
|
47
48
|
|
|
48
49
|
/*----------------------------------
|
|
49
50
|
- CONFIG
|
|
@@ -51,7 +52,7 @@ type TServiceUseOptions = {
|
|
|
51
52
|
|
|
52
53
|
const LogPrefix = '[service]';
|
|
53
54
|
|
|
54
|
-
export function Route(options: TControllerDefinition = {}) {
|
|
55
|
+
export function Route(options: Omit<TControllerDefinition, 'controller'> = {}) {
|
|
55
56
|
return function (
|
|
56
57
|
target: any,
|
|
57
58
|
propertyKey: string,
|
|
@@ -73,6 +74,7 @@ export function Route(options: TControllerDefinition = {}) {
|
|
|
73
74
|
method: 'POST',
|
|
74
75
|
path: '/api/' + options.path,
|
|
75
76
|
controller: originalMethod,
|
|
77
|
+
schema: options.schema,
|
|
76
78
|
options: {
|
|
77
79
|
priority: options.priority || 0
|
|
78
80
|
}
|
|
@@ -90,36 +92,33 @@ export function Route(options: TControllerDefinition = {}) {
|
|
|
90
92
|
- CLASS
|
|
91
93
|
----------------------------------*/
|
|
92
94
|
export default abstract class Service<
|
|
93
|
-
TConfig extends
|
|
95
|
+
TConfig extends {},
|
|
94
96
|
THooks extends THooksList,
|
|
95
|
-
TApplication extends Application
|
|
96
|
-
TServicesIndex extends StartedServicesIndex = {}
|
|
97
|
+
TApplication extends Application
|
|
97
98
|
> {
|
|
98
99
|
|
|
99
100
|
public started?: Promise<void>;
|
|
100
|
-
public status: 'stopped' | 'starting' | 'running' | 'paused' = '
|
|
101
|
+
public status: 'stopped' | 'starting' | 'running' | 'paused' = 'starting';
|
|
101
102
|
|
|
102
103
|
public commands?: Command[];
|
|
103
104
|
public metas!: TServiceMetas;
|
|
104
105
|
public bindings: string[] = []
|
|
105
106
|
|
|
106
107
|
public app: TApplication;
|
|
108
|
+
public config: TConfig = {} as TConfig;
|
|
107
109
|
|
|
108
|
-
public constructor(
|
|
109
|
-
public parent: AnyService | 'self',
|
|
110
|
-
public config: TConfig,
|
|
111
|
-
// Make this argument appear as instanciated sercices index
|
|
112
|
-
// But actually, Setup.use returns a registered service, not yet launched
|
|
113
|
-
public getServices: TServicesIndex,
|
|
114
|
-
app: TApplication | 'self'
|
|
115
|
-
) {
|
|
110
|
+
public constructor(...[parent, getConfig, app]: TServiceArgs<AnyService>) {
|
|
116
111
|
|
|
112
|
+
this.parent = parent;
|
|
117
113
|
if (this.parent === 'self')
|
|
118
114
|
this.parent = this;
|
|
119
115
|
|
|
120
116
|
this.app = app === 'self'
|
|
121
117
|
? this as unknown as TApplication
|
|
122
118
|
: app
|
|
119
|
+
|
|
120
|
+
if (typeof getConfig === 'function')
|
|
121
|
+
this.config = getConfig(this);
|
|
123
122
|
|
|
124
123
|
}
|
|
125
124
|
|
|
@@ -127,8 +126,6 @@ export default abstract class Service<
|
|
|
127
126
|
return this;
|
|
128
127
|
}
|
|
129
128
|
|
|
130
|
-
public services: TServicesIndex = {} as TServicesIndex;
|
|
131
|
-
|
|
132
129
|
/*----------------------------------
|
|
133
130
|
- LIFECYCLE
|
|
134
131
|
----------------------------------*/
|
|
@@ -141,13 +138,17 @@ export default abstract class Service<
|
|
|
141
138
|
- SUBSERVICES
|
|
142
139
|
----------------------------------*/
|
|
143
140
|
|
|
144
|
-
|
|
141
|
+
// TODO:; babel plugin: transform Service references to app.use('Service')
|
|
142
|
+
public use<TService extends AnyService = AnyService>(
|
|
143
|
+
serviceId: string,
|
|
144
|
+
useOptions: { optional?: boolean } = {}
|
|
145
|
+
): TService {
|
|
145
146
|
|
|
146
|
-
const
|
|
147
|
-
if (
|
|
148
|
-
throw new Error(`Service ${
|
|
147
|
+
const registeredService = this.app.registered[serviceId];
|
|
148
|
+
if (registeredService === undefined && useOptions.optional === false)
|
|
149
|
+
throw new Error(`Service ${registeredService} not registered.`);
|
|
149
150
|
|
|
150
|
-
return this.app[
|
|
151
|
+
return this.app[ registeredService.name ];
|
|
151
152
|
}
|
|
152
153
|
|
|
153
154
|
/*----------------------------------
|
|
@@ -182,13 +183,7 @@ export default abstract class Service<
|
|
|
182
183
|
//this.config.debug && console.info(`[hook] Run all ${name} hook (${callbacks.length}).`);
|
|
183
184
|
return Promise.all(
|
|
184
185
|
callbacks.map(
|
|
185
|
-
cb => cb(...args)
|
|
186
|
-
|
|
187
|
-
if (name !== 'error')
|
|
188
|
-
this.runHook('error', e);
|
|
189
|
-
else
|
|
190
|
-
console.error(`[hook] Error while executing hook ${name}:`, e);
|
|
191
|
-
})
|
|
186
|
+
cb => cb(...args)
|
|
192
187
|
)
|
|
193
188
|
).then(() => {
|
|
194
189
|
//this.config.debug && console.info(`[hook] Hooks ${name} executed with success.`);
|
|
@@ -49,10 +49,6 @@ export type THooks = {
|
|
|
49
49
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
export type TServices = {
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
52
|
export type TBasicUser = {
|
|
57
53
|
type: string,
|
|
58
54
|
name: string,
|
|
@@ -73,13 +69,11 @@ export default abstract class AuthService<
|
|
|
73
69
|
TApplication extends Application,
|
|
74
70
|
TJwtSession extends TBasicJwtSession = TBasicJwtSession,
|
|
75
71
|
TRequest extends ServerRequest<Router> = ServerRequest<Router>,
|
|
76
|
-
> extends Service<TConfig, THooks, TApplication
|
|
72
|
+
> extends Service<TConfig, THooks, TApplication> {
|
|
77
73
|
|
|
78
|
-
public abstract login( ...args: any[] ): Promise<{ user: TUser, token: string }>;
|
|
74
|
+
//public abstract login( ...args: any[] ): Promise<{ user: TUser, token: string }>;
|
|
79
75
|
public abstract decodeSession( jwt: TJwtSession, req: THttpRequest ): Promise<TUser | null>;
|
|
80
76
|
|
|
81
|
-
protected abstract displaySessionName(session: TJwtSession): string;
|
|
82
|
-
|
|
83
77
|
// https://beeceptor.com/docs/concepts/authorization-header/#examples
|
|
84
78
|
public async decode( req: THttpRequest, withData: true ): Promise<TUser | null>;
|
|
85
79
|
public async decode( req: THttpRequest, withData?: false ): Promise<TJwtSession | null>;
|
|
@@ -95,6 +89,8 @@ export default abstract class AuthService<
|
|
|
95
89
|
|
|
96
90
|
// Get auth session
|
|
97
91
|
const session = this.getAuthSession(tokenType, token);
|
|
92
|
+
if (session === null)
|
|
93
|
+
return null;
|
|
98
94
|
|
|
99
95
|
// Return email only
|
|
100
96
|
if (!withData) {
|
|
@@ -138,7 +134,7 @@ export default abstract class AuthService<
|
|
|
138
134
|
return { tokenType, token };
|
|
139
135
|
}
|
|
140
136
|
|
|
141
|
-
private getAuthSession( tokenType: string | undefined, token: string ): TJwtSession {
|
|
137
|
+
private getAuthSession( tokenType: string | undefined, token: string ): TJwtSession | null {
|
|
142
138
|
|
|
143
139
|
let session: TJwtSession;
|
|
144
140
|
|
|
@@ -159,10 +155,12 @@ export default abstract class AuthService<
|
|
|
159
155
|
});
|
|
160
156
|
} catch (error) {
|
|
161
157
|
console.warn(LogPrefix, "Failed to decode jwt token:", token);
|
|
162
|
-
|
|
158
|
+
return null;
|
|
159
|
+
//throw new Forbidden(`The JWT token provided in the Authorization header is invalid`);
|
|
163
160
|
}
|
|
164
161
|
} else
|
|
165
|
-
|
|
162
|
+
return null;
|
|
163
|
+
//throw new InputError(`The authorization scheme provided in the Authorization header is unsupported.`);
|
|
166
164
|
|
|
167
165
|
return session;
|
|
168
166
|
}
|
|
@@ -189,9 +187,9 @@ export default abstract class AuthService<
|
|
|
189
187
|
request.res.clearCookie('authorization');
|
|
190
188
|
}
|
|
191
189
|
|
|
192
|
-
public check( request: TRequest, entity: string, role: TUserRole
|
|
193
|
-
public check( request: TRequest, entity: string, role: false
|
|
194
|
-
public check( request: TRequest, entity: string, role: TUserRole | false = 'USER'
|
|
190
|
+
public check( request: TRequest, entity: string, role: TUserRole): TUser;
|
|
191
|
+
public check( request: TRequest, entity: string, role: false): null;
|
|
192
|
+
public check( request: TRequest, entity: string, role: TUserRole | false = 'USER'): TUser | null {
|
|
195
193
|
|
|
196
194
|
const user = request.user;
|
|
197
195
|
|
|
@@ -201,7 +199,7 @@ export default abstract class AuthService<
|
|
|
201
199
|
|
|
202
200
|
throw new Error(`request.user has not been decoded.`);
|
|
203
201
|
|
|
204
|
-
//
|
|
202
|
+
// Shoudln't be logged
|
|
205
203
|
} else if (role === false) {
|
|
206
204
|
|
|
207
205
|
return user;
|
|
@@ -220,13 +218,13 @@ export default abstract class AuthService<
|
|
|
220
218
|
// Insufficient permissions
|
|
221
219
|
} else if (!user.roles.includes(role)) {
|
|
222
220
|
|
|
223
|
-
console.warn(LogPrefix, "Refusé: " + role + " pour " + user.name + " (" + (user.roles
|
|
221
|
+
console.warn(LogPrefix, "Refusé: " + role + " pour " + user.name + " (" + (user.roles || 'role inconnu') + ")");
|
|
224
222
|
|
|
225
223
|
throw new Forbidden("You do not have sufficient permissions to access this resource.");
|
|
226
224
|
|
|
227
225
|
} else {
|
|
228
226
|
|
|
229
|
-
console.warn(LogPrefix, "Autorisé " + role + " pour " + user.name + " (" + user.roles
|
|
227
|
+
console.warn(LogPrefix, "Autorisé " + role + " pour " + user.name + " (" + user.roles + ")");
|
|
230
228
|
|
|
231
229
|
}
|
|
232
230
|
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
// Core
|
|
8
8
|
import {
|
|
9
|
-
default as Router, Request as ServerRequest, TAnyRoute,
|
|
10
|
-
RouterService
|
|
9
|
+
default as Router, Request as ServerRequest, Response as ServerResponse, TAnyRoute,
|
|
10
|
+
RouterService, TRouterServiceArgs
|
|
11
11
|
} from '@server/services/router';
|
|
12
12
|
|
|
13
13
|
// Specific
|
|
@@ -37,30 +37,42 @@ export default class AuthenticationRouterService<
|
|
|
37
37
|
- LIFECYCLE
|
|
38
38
|
----------------------------------*/
|
|
39
39
|
|
|
40
|
-
public users
|
|
40
|
+
public users: UsersService;
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
public constructor(...args: TRouterServiceArgs) {
|
|
43
|
+
super(...args);
|
|
44
|
+
|
|
45
|
+
this.users = this.config.users;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
protected async ready() {
|
|
43
49
|
|
|
44
50
|
// Decode current user
|
|
45
51
|
this.parent.on('request', async (request: TRequest) => {
|
|
46
52
|
|
|
47
53
|
// TODO: Typings. (context.user ?)
|
|
48
|
-
const decoded = await this.
|
|
54
|
+
const decoded = await this.users.decode( request.req, true);
|
|
49
55
|
|
|
50
56
|
request.user = decoded || null;
|
|
51
57
|
})
|
|
52
58
|
|
|
53
59
|
// Check route permissions
|
|
54
|
-
this.parent.on('resolved', async (
|
|
60
|
+
this.parent.on('resolved', async (
|
|
61
|
+
route: TAnyRoute,
|
|
62
|
+
request: TRequest,
|
|
63
|
+
response: ServerResponse<Router>
|
|
64
|
+
) => {
|
|
55
65
|
|
|
56
|
-
if (route.options.auth !== undefined)
|
|
57
|
-
// TODO: How to pas the router type to router config ? Circular rfeerence ?
|
|
58
|
-
this.services.users.check(request, route.options.auth);
|
|
59
|
-
})
|
|
60
|
-
}
|
|
66
|
+
if (route.options.auth !== undefined) {
|
|
61
67
|
|
|
62
|
-
|
|
68
|
+
// Basic auth check
|
|
69
|
+
this.users.check(request, 'User', route.options.auth);
|
|
63
70
|
|
|
71
|
+
// Redirect to logged page
|
|
72
|
+
if (route.options.auth === false && request.user && route.options.redirectLogged)
|
|
73
|
+
response.redirect(route.options.redirectLogged);
|
|
74
|
+
}
|
|
75
|
+
})
|
|
64
76
|
}
|
|
65
77
|
|
|
66
78
|
protected async shutdown() {
|
|
@@ -59,20 +59,17 @@ type TCacheGetOnlyArgs = [
|
|
|
59
59
|
export type Config = {
|
|
60
60
|
debug: boolean,
|
|
61
61
|
disk: string, // TODO: keyof disks
|
|
62
|
+
disks: DisksManager
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
export type Hooks = {
|
|
65
66
|
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
export type Services = {
|
|
69
|
-
disks: DisksManager,
|
|
70
|
-
}
|
|
71
|
-
|
|
72
69
|
/*----------------------------------
|
|
73
70
|
- SERVICE
|
|
74
71
|
----------------------------------*/
|
|
75
|
-
export default class Cache extends Service<Config, Hooks, Application
|
|
72
|
+
export default class Cache extends Service<Config, Hooks, Application> {
|
|
76
73
|
|
|
77
74
|
public commands = registerCommands(this);
|
|
78
75
|
|
|
@@ -83,29 +80,21 @@ export default class Cache extends Service<Config, Hooks, Application, Services>
|
|
|
83
80
|
public constructor(
|
|
84
81
|
parent: AnyService,
|
|
85
82
|
config: Config,
|
|
86
|
-
services: Services,
|
|
87
83
|
app: Application,
|
|
88
84
|
) {
|
|
89
85
|
|
|
90
|
-
super(parent, config,
|
|
86
|
+
super(parent, config, app);
|
|
91
87
|
|
|
92
|
-
this.disk = this.
|
|
88
|
+
this.disk = this.config.disks.get(config.disk)
|
|
93
89
|
}
|
|
94
90
|
|
|
95
91
|
/*----------------------------------
|
|
96
92
|
- LIFECYCLE
|
|
97
93
|
----------------------------------*/
|
|
98
94
|
|
|
99
|
-
protected async start() {
|
|
100
|
-
|
|
101
|
-
setInterval(() => this.cleanMem(), 10000);
|
|
102
|
-
|
|
103
|
-
// Restore persisted data
|
|
104
|
-
//await this.restore();
|
|
105
|
-
}
|
|
106
|
-
|
|
107
95
|
public async ready() {
|
|
108
96
|
|
|
97
|
+
setInterval(() => this.cleanMem(), 10000);
|
|
109
98
|
}
|
|
110
99
|
|
|
111
100
|
public async shutdown() {
|
|
@@ -36,7 +36,7 @@ export type Services = {
|
|
|
36
36
|
- CLASSE
|
|
37
37
|
----------------------------------*/
|
|
38
38
|
|
|
39
|
-
export default class CronManager extends Service<Config, Hooks, Application
|
|
39
|
+
export default class CronManager extends Service<Config, Hooks, Application> {
|
|
40
40
|
|
|
41
41
|
public static taches: { [nom: string]: CronTask } = {}
|
|
42
42
|
public static timer: NodeJS.Timeout;
|
|
@@ -45,7 +45,7 @@ export default class CronManager extends Service<Config, Hooks, Application, Ser
|
|
|
45
45
|
- LIFECICLE
|
|
46
46
|
----------------------------------*/
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
public async ready() {
|
|
49
49
|
|
|
50
50
|
clearInterval(CronManager.timer);
|
|
51
51
|
CronManager.timer = setInterval(() => {
|
|
@@ -54,13 +54,6 @@ export default class CronManager extends Service<Config, Hooks, Application, Ser
|
|
|
54
54
|
CronManager.taches[id].run();
|
|
55
55
|
|
|
56
56
|
}, 10000);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
public async ready() {
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
public async shutdown() {
|
|
64
57
|
|
|
65
58
|
}
|
|
66
59
|
|
|
@@ -10,7 +10,7 @@ const safeStringify = require('fast-safe-stringify'); // remplace les référenc
|
|
|
10
10
|
|
|
11
11
|
// Core: general
|
|
12
12
|
import { Application, Services } from '@server/app';
|
|
13
|
-
import Service, { AnyService, TRegisteredServicesIndex } from '@server/app/service';
|
|
13
|
+
import Service, { AnyService, TRegisteredServicesIndex, TServiceArgs } from '@server/app/service';
|
|
14
14
|
import { NotFound } from '@common/errors';
|
|
15
15
|
|
|
16
16
|
// Services
|
|
@@ -91,20 +91,15 @@ const emptyOkPacket = {
|
|
|
91
91
|
|
|
92
92
|
// TODO: build callable instance sithut instanciating the service
|
|
93
93
|
|
|
94
|
-
export default class SQL extends Service<Config, Hooks, Application
|
|
94
|
+
export default class SQL extends Service<Config, Hooks, Application> {
|
|
95
95
|
|
|
96
96
|
public database: Database;
|
|
97
97
|
|
|
98
|
-
public constructor(
|
|
99
|
-
parent: AnyService,
|
|
100
|
-
config: Config,
|
|
101
|
-
drivers: TRegisteredServicesIndex,
|
|
102
|
-
app: Application,
|
|
103
|
-
) {
|
|
98
|
+
public constructor( ...args: TServiceArgs<SQL>) {
|
|
104
99
|
|
|
105
|
-
super(
|
|
100
|
+
super(...args);
|
|
106
101
|
|
|
107
|
-
this.database = new Database(this, config);
|
|
102
|
+
this.database = new Database(this, this.config);
|
|
108
103
|
}
|
|
109
104
|
|
|
110
105
|
public getServiceInstance() {
|
|
@@ -56,7 +56,7 @@ export type TReadFileOptions = {
|
|
|
56
56
|
export default abstract class FsDriver<
|
|
57
57
|
Config extends TDrivercnfig = TDrivercnfig,
|
|
58
58
|
TBucketName = keyof Config["buckets"]
|
|
59
|
-
> extends Service<Config, {}, Application
|
|
59
|
+
> extends Service<Config, {}, Application> {
|
|
60
60
|
|
|
61
61
|
public abstract mount(): Promise<void>;
|
|
62
62
|
|