5htp-core 0.1.2-3 → 0.2.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/changelog.md +5 -0
- package/doc/TODO.md +71 -0
- package/package.json +5 -4
- package/src/client/{App.tsx → app/component.tsx} +15 -8
- package/src/client/app/index.ts +128 -0
- package/src/client/app/service.ts +34 -0
- package/src/client/app.tsconfig.json +0 -4
- package/src/client/components/Card/index.tsx +1 -1
- package/src/client/components/Dialog/Manager.tsx +39 -12
- package/src/client/components/Form/index.tsx +1 -1
- package/src/client/components/button.tsx +2 -2
- package/src/client/components/containers/Popover/index.tsx +1 -1
- package/src/client/components/data/spintext/index.tsx +1 -1
- package/src/client/components/dropdown/index.tsx +1 -1
- package/src/client/components/index.ts +8 -0
- package/src/client/components/input/BaseV2/index.tsx +1 -1
- package/src/client/components/input/UploadImage/index.tsx +1 -1
- package/src/client/hooks/index.ts +5 -0
- package/src/client/hooks/useState/index.tsx +2 -2
- package/src/client/hooks.ts +22 -0
- package/src/client/index.ts +5 -0
- package/src/client/pages/_layout/landing/index.tsx +0 -2
- package/src/client/pages/_messages/400.tsx +2 -2
- package/src/client/pages/_messages/401.tsx +2 -2
- package/src/client/pages/_messages/403.tsx +2 -2
- package/src/client/pages/_messages/404.tsx +2 -2
- package/src/client/pages/_messages/500.tsx +2 -2
- package/src/client/pages/bug.tsx +1 -1
- package/src/client/pages/useHeader.tsx +1 -1
- package/src/client/{context/captcha.ts → services/captcha/index.ts} +0 -0
- package/src/client/services/metrics/index.ts +37 -0
- package/src/client/{router → services/router/components}/Link.tsx +1 -1
- package/src/client/services/router/components/Page.tsx +59 -0
- package/src/client/{router/component.tsx → services/router/components/router.tsx} +43 -74
- package/src/client/services/router/index.tsx +448 -0
- package/src/client/services/router/request/api.ts +229 -0
- package/src/client/{router → services/router}/request/history.ts +0 -0
- package/src/client/services/router/request/index.ts +52 -0
- package/src/client/services/router/response/index.tsx +107 -0
- package/src/client/services/router/response/page.ts +95 -0
- package/src/client/{context/socket.ts → services/socket/index.ts} +2 -2
- package/src/client/utils/dom.ts +1 -1
- package/src/common/app/index.ts +9 -0
- package/src/common/data/chaines/index.ts +9 -6
- package/src/common/data/input/validate.ts +3 -166
- package/src/common/data/objets.ts +25 -0
- package/src/common/data/tableaux.ts +8 -0
- package/src/common/errors/index.ts +3 -1
- package/src/common/router/index.ts +67 -88
- package/src/common/router/layouts.ts +50 -0
- package/src/common/router/register.ts +62 -0
- package/src/common/router/request/api.ts +72 -0
- package/src/common/router/request/index.ts +31 -0
- package/src/common/router/{response.ts → response/index.ts} +9 -13
- package/src/common/router/response/page.ts +40 -56
- package/src/common/validation/index.ts +3 -0
- package/src/common/validation/schema.ts +184 -0
- package/src/common/validation/validator.ts +88 -0
- package/src/common/validation/validators.ts +313 -0
- package/src/server/app/config.ts +8 -10
- package/src/server/app/index.ts +81 -124
- package/src/server/app/service.ts +98 -0
- package/src/server/app.tsconfig.json +0 -8
- package/src/server/error/index.ts +13 -0
- package/src/server/index.ts +5 -0
- package/src/server/patch.ts +0 -6
- package/src/server/{data/Cache.ts → services/cache/index.ts} +79 -47
- package/src/server/services/console/bugReporter.ts +26 -16
- package/src/server/services/console/index.ts +50 -51
- package/src/server/services/cron/index.ts +12 -26
- package/src/server/services/database/bucket.ts +40 -0
- package/src/server/services/database/connection.ts +206 -75
- package/src/server/services/database/datatypes.ts +63 -40
- package/src/server/services/database/index.ts +295 -272
- package/src/server/services/database/metas.ts +246 -135
- package/src/server/services/database/stats.ts +151 -126
- package/src/server/services/email/index.ts +24 -54
- package/src/server/services/{router/request/services → metrics}/detect.ts +6 -10
- package/src/server/services/{router/request/services/tracking.ts → metrics/index.ts} +68 -45
- package/src/server/services/{http → router/http}/index.ts +19 -47
- package/src/server/services/{http → router/http}/multipart.ts +0 -0
- package/src/server/services/{http → router/http}/session.ts.old +0 -0
- package/src/server/services/router/index.ts +273 -203
- package/src/server/services/router/request/api.ts +73 -0
- package/src/server/services/router/request/index.ts +16 -95
- package/src/server/services/router/request/service.ts +21 -0
- package/src/server/services/router/response/index.ts +125 -64
- package/src/server/services/router/response/{filter → mask}/Filter.ts +0 -0
- package/src/server/services/router/response/{filter → mask}/index.ts +0 -2
- package/src/server/services/router/response/{filter → mask}/selecteurs.ts +0 -0
- package/src/server/services/router/response/page/document.tsx +194 -0
- package/src/server/services/router/response/page/index.tsx +157 -0
- package/src/server/{libs/pages → services/router/response/page}/schemaGenerator.ts +0 -0
- package/src/server/services/router/service.ts +48 -0
- package/src/server/services/schema/index.ts +47 -0
- package/src/server/services/schema/request.ts +55 -0
- package/src/server/services/schema/router.ts +33 -0
- package/src/server/services/socket/index.ts +38 -43
- package/src/server/services/socket/scope.ts +6 -4
- package/src/server/services/users/index.ts +203 -0
- package/src/server/services/{auth/base.ts → users/old.ts} +20 -111
- package/src/server/services/users/router/index.ts +72 -0
- package/src/server/services/users/router/request.ts +49 -0
- package/src/types/aliases.d.ts +43 -2
- package/templates/composant.tsx +1 -1
- package/templates/modal.tsx +1 -1
- package/templates/page.tsx +1 -1
- package/tsconfig.common.json +0 -4
- package/src/client/context/api.ts +0 -92
- package/src/client/context/index.ts +0 -246
- package/src/client/index.tsx +0 -129
- package/src/client/router/index.ts +0 -286
- package/src/client/router/request/index.ts +0 -106
- package/src/client/router/response/index.ts +0 -38
- package/src/client/router/route.ts +0 -75
- package/src/common/data/input/validators/basic.ts +0 -299
- package/src/common/data/input/validators/build.ts +0 -63
- package/src/common/router/request.ts +0 -83
- package/src/server/data/ApiClient.ts +0 -119
- package/src/server/data/input.ts +0 -41
- package/src/server/libs/pages/document.static.tsx +0 -41
- package/src/server/libs/pages/document.tsx +0 -203
- package/src/server/libs/pages/render.tsx +0 -90
- package/src/server/routes/auth.ts +0 -151
- package/src/server/services/redis/index.ts +0 -71
- package/src/server/services/router/request/services/auth.ts +0 -177
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
- OUTILS DE TRAITEMENT
|
|
3
3
|
----------------------------------*/
|
|
4
4
|
|
|
5
|
-
//
|
|
5
|
+
// Npm
|
|
6
6
|
import hInterval from 'human-interval';
|
|
7
7
|
|
|
8
|
-
//
|
|
9
|
-
import
|
|
10
|
-
import
|
|
8
|
+
// Core
|
|
9
|
+
import Service from '@server/app/service';
|
|
10
|
+
import type CacheService from '../cache';
|
|
11
|
+
import type SQL from '../database';
|
|
11
12
|
|
|
12
13
|
/*----------------------------------
|
|
13
14
|
- CONST
|
|
@@ -41,6 +42,11 @@ const debug = false;
|
|
|
41
42
|
/*----------------------------------
|
|
42
43
|
- TYPES
|
|
43
44
|
----------------------------------*/
|
|
45
|
+
|
|
46
|
+
type TStatsServiceConfig = {
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
44
50
|
type TObjDonneesStats = { [cheminStats: string]: number }
|
|
45
51
|
export type TStat<TDonnees extends TObjDonneesStats> = { date: string } & TDonnees
|
|
46
52
|
export type TTimeStat<TDonnees extends TObjDonneesStats> = { time: number } & TDonnees
|
|
@@ -55,141 +61,160 @@ type TRetourStats<TDonnees extends TObjDonneesStats> = {
|
|
|
55
61
|
interval: number,
|
|
56
62
|
}
|
|
57
63
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
// Query
|
|
63
|
-
where,
|
|
64
|
-
// time
|
|
65
|
-
period, interval,
|
|
66
|
-
// Options
|
|
67
|
-
relative, cache
|
|
68
|
-
|
|
69
|
-
}: {
|
|
70
|
-
// Database
|
|
71
|
-
where?: string,
|
|
72
|
-
// Time
|
|
73
|
-
period: string,
|
|
74
|
-
interval: string,
|
|
75
|
-
// Options
|
|
76
|
-
relative?: boolean,
|
|
77
|
-
cache?: { id: string, duration?: string },
|
|
78
|
-
}): Promise< TRetourStats<TDonnees> > {
|
|
79
|
-
|
|
80
|
-
if (!debug && cache !== undefined) {
|
|
81
|
-
const fromCache = await Cache.getVal<TRetourStats<TDonnees>>(cache.id);
|
|
82
|
-
if (fromCache !== null) {
|
|
83
|
-
console.log("Using value from cache " + cache.id);
|
|
84
|
-
return fromCache;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
64
|
+
/*----------------------------------
|
|
65
|
+
- SERVICE
|
|
66
|
+
----------------------------------*/
|
|
67
|
+
export default class StatsService extends Service<TStatsServiceConfig> {
|
|
87
68
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const periodSec = Math.floor(periodTime / 1000);
|
|
94
|
-
|
|
95
|
-
const startTime = scaleTime(Date.now() - periodTime, intervalTime); // Round start date to the specified interval
|
|
96
|
-
const endTime = scaleTime(Date.now(), intervalTime);
|
|
97
|
-
const stats: TRetourStats<TDonnees> = {
|
|
98
|
-
graph: [],
|
|
99
|
-
stats: {} as TDonnees,
|
|
100
|
-
start: new Date(startTime),
|
|
101
|
-
end: new Date(endTime),
|
|
102
|
-
interval: intervalTime
|
|
103
|
-
}
|
|
69
|
+
public constructor(
|
|
70
|
+
config: TStatsServiceConfig,
|
|
71
|
+
private cache: CacheService,
|
|
72
|
+
private sql: SQL
|
|
73
|
+
) {
|
|
104
74
|
|
|
105
|
-
|
|
106
|
-
let previousRow: TObjetDonnees = {};
|
|
107
|
-
|
|
108
|
-
const selector = statsCols(columns, relative ? 'SUM' : '');
|
|
109
|
-
|
|
110
|
-
// Fetch data (initial point + variations)
|
|
111
|
-
// Since values are relative, we will use stats.total as initialValues,
|
|
112
|
-
// and then increment it to get the latest tota value
|
|
113
|
-
([[previousRow], rows] = await $.sql.query(`
|
|
114
|
-
|
|
115
|
-
# Latest values before start time
|
|
116
|
-
SELECT ${selector}
|
|
117
|
-
FROM ${table}
|
|
118
|
-
WHERE date < (NOW() - INTERVAL ${periodSec} SECOND) ${where ? 'AND ' + where : ''}
|
|
119
|
-
ORDER BY date DESC
|
|
120
|
-
LIMIT 1;
|
|
121
|
-
|
|
122
|
-
# First value for each peiod of time
|
|
123
|
-
SELECT ${selector},
|
|
124
|
-
FLOOR( UNIX_TIMESTAMP(date) * 1000 / ${intervalTime}) * ${intervalTime} as periodTime
|
|
125
|
-
FROM ${table}
|
|
126
|
-
WHERE (date BETWEEN (NOW() - INTERVAL ${periodSec} SECOND) AND NOW())
|
|
127
|
-
${where ? 'AND ' + where : ''}
|
|
128
|
-
|
|
129
|
-
# In addition of the variations between start and end date, we take the latest values
|
|
130
|
-
GROUP BY (date = (SELECT MAX(date) FROM core.NetworkStats)), periodTime
|
|
131
|
-
ORDER BY date DESC;
|
|
132
|
-
|
|
133
|
-
`) as [[TDonnees | undefined], TDonnees[]]);
|
|
134
|
-
|
|
135
|
-
// Process
|
|
136
|
-
if (rows.length === 0)
|
|
137
|
-
return stats;
|
|
138
|
-
if (previousRow === undefined)
|
|
139
|
-
previousRow = {};
|
|
75
|
+
super(config);
|
|
140
76
|
|
|
141
|
-
|
|
77
|
+
}
|
|
142
78
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
for (const { periodTime, ...row } of rows)
|
|
146
|
-
periods[periodTime] = row;
|
|
79
|
+
public async register() {}
|
|
80
|
+
public async start() {}
|
|
147
81
|
|
|
148
|
-
|
|
149
|
-
|
|
82
|
+
public async fetchStats<TDonnees extends TObjDonneesStats>(
|
|
83
|
+
|
|
84
|
+
table: string, columns: (string | [string, string])[], {
|
|
85
|
+
|
|
86
|
+
// Query
|
|
87
|
+
where,
|
|
88
|
+
// time
|
|
89
|
+
period, interval,
|
|
90
|
+
// Options
|
|
91
|
+
relative, cache
|
|
92
|
+
|
|
93
|
+
}: {
|
|
94
|
+
// Database
|
|
95
|
+
where?: string,
|
|
96
|
+
// Time
|
|
97
|
+
period: string,
|
|
98
|
+
interval: string,
|
|
99
|
+
// Options
|
|
100
|
+
relative?: boolean,
|
|
101
|
+
cache?: { id: string, duration?: string },
|
|
102
|
+
}): Promise< TRetourStats<TDonnees> > {
|
|
103
|
+
|
|
104
|
+
if (!debug && cache !== undefined) {
|
|
105
|
+
const fromCache = await this.cache.get<TRetourStats<TDonnees>>(cache.id);
|
|
106
|
+
if (fromCache !== null) {
|
|
107
|
+
console.log("Using value from cache " + cache.id);
|
|
108
|
+
return fromCache.value;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
150
111
|
|
|
151
|
-
|
|
152
|
-
|
|
112
|
+
// NOTE: On ne génère pas le timestamp via la bdd pour éviter les incohérences de timezone
|
|
113
|
+
const periodTime = hInterval(period);
|
|
114
|
+
if (periodTime === undefined) throw new Error(`Invalid period string: ` + period);
|
|
115
|
+
const intervalTime = hInterval(interval);
|
|
116
|
+
if (intervalTime === undefined) throw new Error(`Invalid interval string: ` + interval);
|
|
117
|
+
const periodSec = Math.floor(periodTime / 1000);
|
|
118
|
+
|
|
119
|
+
const startTime = scaleTime(Date.now() - periodTime, intervalTime); // Round start date to the specified interval
|
|
120
|
+
const endTime = scaleTime(Date.now(), intervalTime);
|
|
121
|
+
const stats: TRetourStats<TDonnees> = {
|
|
122
|
+
graph: [],
|
|
123
|
+
stats: {} as TDonnees,
|
|
124
|
+
start: new Date(startTime),
|
|
125
|
+
end: new Date(endTime),
|
|
126
|
+
interval: intervalTime
|
|
127
|
+
}
|
|
153
128
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
continue;
|
|
129
|
+
let rows: TDonnees[];
|
|
130
|
+
let previousRow: TObjetDonnees = {};
|
|
157
131
|
|
|
158
|
-
|
|
132
|
+
const selector = statsCols(columns, relative ? 'SUM' : '');
|
|
133
|
+
|
|
134
|
+
// Fetch data (initial point + variations)
|
|
135
|
+
// Since values are relative, we will use stats.total as initialValues,
|
|
136
|
+
// and then increment it to get the latest tota value
|
|
137
|
+
([[previousRow], rows] = await this.sql.query(`
|
|
138
|
+
|
|
139
|
+
# Latest values before start time
|
|
140
|
+
SELECT ${selector}
|
|
141
|
+
FROM ${table}
|
|
142
|
+
WHERE date < (NOW() - INTERVAL ${periodSec} SECOND) ${where ? 'AND ' + where : ''}
|
|
143
|
+
ORDER BY date DESC
|
|
144
|
+
LIMIT 1;
|
|
145
|
+
|
|
146
|
+
# First value for each peiod of time
|
|
147
|
+
SELECT ${selector},
|
|
148
|
+
FLOOR( UNIX_TIMESTAMP(date) * 1000 / ${intervalTime}) * ${intervalTime} as periodTime
|
|
149
|
+
FROM ${table}
|
|
150
|
+
WHERE (date BETWEEN (NOW() - INTERVAL ${periodSec} SECOND) AND NOW())
|
|
151
|
+
${where ? 'AND ' + where : ''}
|
|
152
|
+
|
|
153
|
+
# In addition of the variations between start and end date, we take the latest values
|
|
154
|
+
GROUP BY (date = (SELECT MAX(date) FROM core.NetworkStats)), periodTime
|
|
155
|
+
ORDER BY date DESC;
|
|
156
|
+
|
|
157
|
+
`) as [[TDonnees | undefined], TDonnees[]]);
|
|
158
|
+
|
|
159
|
+
// Process
|
|
160
|
+
if (rows.length === 0)
|
|
161
|
+
return stats;
|
|
162
|
+
if (previousRow === undefined)
|
|
163
|
+
previousRow = {};
|
|
164
|
+
|
|
165
|
+
rows.reverse();
|
|
166
|
+
|
|
167
|
+
// Index entries by time
|
|
168
|
+
const periods: { [periodTime: number]: TTimeStat<TDonnees> } = {};
|
|
169
|
+
for (const { periodTime, ...row } of rows)
|
|
170
|
+
periods[periodTime] = row;
|
|
171
|
+
|
|
172
|
+
// Completion
|
|
173
|
+
for (let time = startTime; time <= endTime; time += intervalTime) {
|
|
174
|
+
|
|
175
|
+
const row = relative ? { ...previousRow, time } : { time };
|
|
176
|
+
stats.graph.push(row);
|
|
177
|
+
|
|
178
|
+
// No data for this period
|
|
179
|
+
if (periods[time] === undefined)
|
|
180
|
+
continue;
|
|
181
|
+
|
|
182
|
+
for (const nom in periods[time]) {
|
|
159
183
|
|
|
160
|
-
|
|
184
|
+
const value = periods[time][nom];
|
|
161
185
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
186
|
+
row[nom] = (relative && typeof row[nom] === 'number')
|
|
187
|
+
? row[nom] + value
|
|
188
|
+
: value;
|
|
165
189
|
|
|
166
|
-
|
|
190
|
+
}
|
|
167
191
|
|
|
168
|
-
|
|
169
|
-
|
|
192
|
+
previousRow = { ...row };
|
|
193
|
+
}
|
|
170
194
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
195
|
+
// Total = latest known values
|
|
196
|
+
stats.stats = previousRow;
|
|
197
|
+
|
|
198
|
+
// Check if the times selected from the database matches with the times iéterated from the completion
|
|
199
|
+
if (debug) {
|
|
200
|
+
for (const period in periods)
|
|
201
|
+
if (!stats.graph.find( g => g.time.toString() === period )) {
|
|
202
|
+
console.warn(
|
|
203
|
+
`The timetamps selected from the database do not match with the one generated by the completion function`,
|
|
204
|
+
'\nStart date:', startTime, stats.start.toISOString(), ' End date:', endTime, stats.end.toISOString(),
|
|
205
|
+
'\nFrom database', Object.keys(periods).map(time => time + ' (' + new Date( parseInt(time) ).toISOString() + ')'),
|
|
206
|
+
'\nFrom completion (now - period ; now):', stats.graph.map(g => g.time + ' (' + new Date(g.time).toISOString() + ')')
|
|
207
|
+
);
|
|
208
|
+
throw new Error("Integrity check failed.");
|
|
209
|
+
|
|
210
|
+
}
|
|
185
211
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
console.log(cache?.id, "Cumulative stats: total =", stats.stats, "rows =", rows, "periods =", periods, "stats =", stats);
|
|
189
|
-
}
|
|
212
|
+
console.log(cache?.id, "Cumulative stats: total =", stats.stats, "rows =", rows, "periods =", periods, "stats =", stats);
|
|
213
|
+
}
|
|
190
214
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
215
|
+
if (cache !== undefined)
|
|
216
|
+
await this.cache.set( cache.id, stats, cache.duration || interval );
|
|
217
|
+
|
|
218
|
+
return stats;
|
|
219
|
+
}
|
|
195
220
|
}
|
|
@@ -7,39 +7,38 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
// Core
|
|
10
|
-
import
|
|
11
|
-
//import templates from './templates';
|
|
12
|
-
const templates = {} as {[template: string]: (data: any) => string}
|
|
10
|
+
import Application, { Service } from '@server/app';
|
|
13
11
|
import { jsonToHtml } from './utils';
|
|
14
12
|
|
|
13
|
+
const templates = {} as {[template: string]: (data: any) => string}
|
|
14
|
+
|
|
15
15
|
/*----------------------------------
|
|
16
16
|
- SERVICE CONFIG
|
|
17
17
|
----------------------------------*/
|
|
18
18
|
|
|
19
|
-
export type
|
|
19
|
+
export type Config = {
|
|
20
20
|
debug: boolean,
|
|
21
21
|
default: {
|
|
22
22
|
transporter: string,
|
|
23
23
|
from: string
|
|
24
24
|
},
|
|
25
|
-
transporters:
|
|
25
|
+
transporters: Config.EmailTransporters,
|
|
26
26
|
bugReport: {
|
|
27
27
|
from: string,
|
|
28
28
|
to: string
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
export type Hooks = {
|
|
33
|
+
|
|
34
|
+
}
|
|
35
|
+
|
|
32
36
|
declare global {
|
|
33
|
-
namespace
|
|
37
|
+
namespace Config {
|
|
34
38
|
interface EmailTransporters { }
|
|
35
|
-
namespace Config {
|
|
36
|
-
interface Services {
|
|
37
|
-
email: EmailServiceConfig
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
|
-
|
|
41
|
+
|
|
43
42
|
/*----------------------------------
|
|
44
43
|
- TYPES: EMAILS
|
|
45
44
|
----------------------------------*/
|
|
@@ -79,42 +78,25 @@ type TOptions = {
|
|
|
79
78
|
testing?: boolean
|
|
80
79
|
}
|
|
81
80
|
|
|
82
|
-
const config = app.config.email;
|
|
83
|
-
|
|
84
81
|
/*----------------------------------
|
|
85
82
|
- FONCTIONS
|
|
86
83
|
----------------------------------*/
|
|
87
|
-
export default class Email {
|
|
84
|
+
export default class Email extends Service<Config, Hooks, Application> {
|
|
85
|
+
|
|
86
|
+
public async register() {
|
|
88
87
|
|
|
89
|
-
private transporters = {} as {[name: string]: Transporter};
|
|
90
|
-
public register( name: string, transporter: (new () => Transporter) ) {
|
|
91
|
-
console.log(`[email] registering email transporter: ${name}`);
|
|
92
|
-
this.transporters[ name ] = new transporter();
|
|
93
88
|
}
|
|
94
89
|
|
|
95
|
-
public
|
|
96
|
-
$.console.bugReport.addTransporter('email', (report) => this.send(report.type === 'server' ? {
|
|
97
|
-
from: config.bugReport.from,
|
|
98
|
-
to: config.bugReport.to,
|
|
99
|
-
subject: "Bug on server: " + (report.error.message),
|
|
100
|
-
html: `
|
|
101
|
-
<a href="${app.services.http.publicUrl}/admin/activity/requests/${report.channelId}">
|
|
102
|
-
View Request details & console
|
|
103
|
-
</a>
|
|
104
|
-
<br/>
|
|
105
|
-
${report.logs}
|
|
106
|
-
`
|
|
107
|
-
} : {
|
|
108
|
-
from: config.bugReport.from,
|
|
109
|
-
to: config.bugReport.to,
|
|
110
|
-
subject: "Bug on application " + (report.action),
|
|
111
|
-
html: {
|
|
112
|
-
...report
|
|
113
|
-
}
|
|
114
|
-
}));
|
|
90
|
+
public async start() {
|
|
115
91
|
|
|
116
92
|
}
|
|
117
93
|
|
|
94
|
+
private transporters = {} as {[name: string]: Transporter};
|
|
95
|
+
public addTransporter( name: string, transporter: (new () => Transporter) ) {
|
|
96
|
+
console.log(`[email] registering email transporter: ${name}`);
|
|
97
|
+
this.transporters[ name ] = new transporter();
|
|
98
|
+
}
|
|
99
|
+
|
|
118
100
|
public async send(
|
|
119
101
|
emails: TEmail | TEmail[],
|
|
120
102
|
options: TOptions = {}
|
|
@@ -124,12 +106,12 @@ export default class Email {
|
|
|
124
106
|
if (!Array.isArray( emails ))
|
|
125
107
|
emails = [emails];
|
|
126
108
|
|
|
127
|
-
config.debug && console.log(`Preparing to send ${emails.length} emails ...`);
|
|
109
|
+
this.config.debug && console.log(`Preparing to send ${emails.length} emails ...`);
|
|
128
110
|
|
|
129
111
|
const emailsToSend: TCompleteEmail[] = emails.map(email => {
|
|
130
112
|
|
|
131
113
|
const from = email.from === undefined
|
|
132
|
-
? config.default.from
|
|
114
|
+
? this.config.default.from
|
|
133
115
|
: email.from;
|
|
134
116
|
|
|
135
117
|
const to = typeof email.to === 'string'
|
|
@@ -170,7 +152,7 @@ export default class Email {
|
|
|
170
152
|
|
|
171
153
|
});
|
|
172
154
|
|
|
173
|
-
const transporterName = options.transporter ||
|
|
155
|
+
const transporterName = options.transporter || this.config.default.transporter;
|
|
174
156
|
if (transporterName === undefined)
|
|
175
157
|
throw new Error(`Please define at least one mail transporter.`);
|
|
176
158
|
|
|
@@ -192,16 +174,4 @@ export default class Email {
|
|
|
192
174
|
await Transporter.send(emailsToSend);
|
|
193
175
|
|
|
194
176
|
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/*----------------------------------
|
|
198
|
-
- REGISTER SERVICE
|
|
199
|
-
----------------------------------*/
|
|
200
|
-
app.register('email', Email);
|
|
201
|
-
declare global {
|
|
202
|
-
namespace Core {
|
|
203
|
-
interface Services {
|
|
204
|
-
email: Email;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
177
|
}
|
|
@@ -3,17 +3,14 @@
|
|
|
3
3
|
----------------------------------*/
|
|
4
4
|
|
|
5
5
|
// Npm
|
|
6
|
-
import
|
|
6
|
+
import got from 'got';
|
|
7
7
|
|
|
8
8
|
// Core
|
|
9
9
|
import { Forbidden } from '@common/errors';
|
|
10
|
-
import
|
|
11
|
-
import ServerRequest from '..';
|
|
12
|
-
import TrackerService from './tracking';
|
|
10
|
+
import ServerRequest from '../router/request';
|
|
13
11
|
|
|
14
12
|
// App
|
|
15
13
|
import app from '@server/app';
|
|
16
|
-
import { IP } from '@models';
|
|
17
14
|
|
|
18
15
|
/*----------------------------------
|
|
19
16
|
- TYPES
|
|
@@ -94,14 +91,13 @@ export default class ProtectService {
|
|
|
94
91
|
if (!token)
|
|
95
92
|
throw new Forbidden("Le captcha n'a pas été complété.");
|
|
96
93
|
|
|
97
|
-
const res = await
|
|
98
|
-
|
|
94
|
+
const res = await got.post('https://www.google.com/recaptcha/api/siteverify', {
|
|
95
|
+
body: JSON.stringify({
|
|
99
96
|
secret: app.config.http.security.recaptcha.prv,
|
|
100
97
|
response: token,
|
|
101
98
|
remoteip: null
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
}).then(res => res.data)
|
|
99
|
+
})
|
|
100
|
+
}).json()
|
|
105
101
|
|
|
106
102
|
console.info(`Réponse captcha`, res);
|
|
107
103
|
|