@silexlabs/silex 3.0.0-alpha.47 → 3.0.0-alpha.49
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/.env.default +1 -1
- package/dist/client/client/api.d.ts +1 -1
- package/dist/client/client/config.d.ts +2 -0
- package/dist/client/css/admin.css +15 -0
- package/dist/client/js/main.js +3 -3
- package/dist/client/types.d.ts +1 -1
- package/dist/plugins/client/plugins/client/website-info.d.ts +1 -0
- package/dist/plugins/client/plugins/client/website-info.js +55 -0
- package/dist/plugins/client/plugins/client/website-info.js.map +1 -0
- package/dist/plugins/client/types.d.ts +1 -1
- package/dist/plugins/server/plugins/server/GitlabConnector.d.ts +11 -0
- package/dist/plugins/server/plugins/server/GitlabConnector.js +143 -33
- package/dist/plugins/server/plugins/server/GitlabConnector.js.map +1 -1
- package/dist/plugins/server/plugins/server/SslPlugin.js +5 -5
- package/dist/plugins/server/plugins/server/SslPlugin.js.map +1 -1
- package/dist/plugins/server/plugins/server/StaticPlugin.js +4 -0
- package/dist/plugins/server/plugins/server/StaticPlugin.js.map +1 -1
- package/dist/plugins/server/server/config.js +4 -5
- package/dist/plugins/server/server/config.js.map +1 -1
- package/dist/plugins/server/server/connectors/FsStorage.js +1 -1
- package/dist/plugins/server/server/connectors/FsStorage.js.map +1 -1
- package/dist/plugins/server/types.d.ts +1 -1
- package/dist/server/server/config.js +4 -5
- package/dist/server/server/connectors/FsStorage.js +1 -1
- package/dist/server/server/express.js +2 -2
- package/package.json +1 -1
- package/public/silex.js +5 -0
- package/src/css/grapesjs.scss +1 -0
- package/src/css/index.scss +1 -0
- package/src/css/website-info.scss +13 -0
- package/src/ts/client/api.ts +2 -2
- package/src/ts/client/config.ts +3 -0
- package/src/ts/client/grapesjs/LoginDialog.ts +0 -1
- package/src/ts/client/grapesjs/settings.ts +1 -1
- package/src/ts/client/grapesjs/storage.ts +0 -1
- package/src/ts/client/index.ts +1 -3
- package/src/ts/plugins/client/website-info.ts +63 -0
- package/src/ts/plugins/server/GitlabConnector.ts +154 -34
- package/src/ts/plugins/server/SslPlugin.ts +5 -5
- package/src/ts/plugins/server/StaticPlugin.ts +4 -0
- package/src/ts/server/config.ts +4 -5
- package/src/ts/server/connectors/FsStorage.ts +1 -1
- package/src/ts/server/express.ts +2 -2
- package/src/ts/types.ts +1 -1
|
@@ -21,7 +21,6 @@ import { ConnectorFile, ConnectorFileContent, StatusCallback, StorageConnector,
|
|
|
21
21
|
import { ApiError, ConnectorType, ConnectorUser, WebsiteData, WebsiteId, WebsiteMeta, WebsiteMetaFileContent } from '../../types'
|
|
22
22
|
import fetch from 'node-fetch'
|
|
23
23
|
import crypto, { createHash } from 'crypto'
|
|
24
|
-
import { PassThrough, Readable } from 'stream'
|
|
25
24
|
|
|
26
25
|
/**
|
|
27
26
|
* Gitlab connector
|
|
@@ -34,6 +33,8 @@ export interface GitlabOptions {
|
|
|
34
33
|
clientSecret: string
|
|
35
34
|
branch: string
|
|
36
35
|
assetsFolder: string
|
|
36
|
+
metaRepo: string
|
|
37
|
+
metaRepoFile: string
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
interface GitlabToken {
|
|
@@ -50,6 +51,7 @@ interface GitlabToken {
|
|
|
50
51
|
scope: string
|
|
51
52
|
}
|
|
52
53
|
userId?: number
|
|
54
|
+
username?: string
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
interface GitlabSession {
|
|
@@ -65,7 +67,7 @@ interface GitlabAction {
|
|
|
65
67
|
interface GitlabWriteFile {
|
|
66
68
|
branch: string
|
|
67
69
|
commit_message: string
|
|
68
|
-
id
|
|
70
|
+
id?: string
|
|
69
71
|
actions?: GitlabAction[]
|
|
70
72
|
content?: string
|
|
71
73
|
file_path?: string
|
|
@@ -90,6 +92,16 @@ interface GitlabCreateBranch {
|
|
|
90
92
|
ref: string
|
|
91
93
|
}
|
|
92
94
|
|
|
95
|
+
interface MetaRepoFileContent {
|
|
96
|
+
websites: {
|
|
97
|
+
[websiteId: string]: {
|
|
98
|
+
meta: WebsiteMetaFileContent,
|
|
99
|
+
createdAt: string,
|
|
100
|
+
updatedAt: string,
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
93
105
|
async function wait(ms: number) {
|
|
94
106
|
return new Promise(resolve => setTimeout(resolve, ms))
|
|
95
107
|
}
|
|
@@ -107,7 +119,9 @@ export default class GitlabConnector implements StorageConnector {
|
|
|
107
119
|
constructor(private config: ServerConfig, opts: Partial<GitlabOptions>) {
|
|
108
120
|
this.options = {
|
|
109
121
|
branch: 'main',
|
|
110
|
-
assetsFolder: '',
|
|
122
|
+
assetsFolder: 'assets',
|
|
123
|
+
metaRepo: 'silex-meta',
|
|
124
|
+
metaRepoFile: 'websites.json',
|
|
111
125
|
...opts,
|
|
112
126
|
} as GitlabOptions
|
|
113
127
|
if(!this.options.clientId) throw new Error('Missing Gitlab client ID')
|
|
@@ -117,7 +131,7 @@ export default class GitlabConnector implements StorageConnector {
|
|
|
117
131
|
// **
|
|
118
132
|
// Convenience methods for the Gitlab API
|
|
119
133
|
private getAssetPath(path: string): string {
|
|
120
|
-
return `${this.options.assetsFolder}${path}`
|
|
134
|
+
return encodeURIComponent(`${this.options.assetsFolder}${path}`)
|
|
121
135
|
}
|
|
122
136
|
|
|
123
137
|
private async createFile(session: GitlabSession, websiteId: WebsiteId, path: string, content: string, isBase64 = false): Promise<void> {
|
|
@@ -144,6 +158,36 @@ export default class GitlabConnector implements StorageConnector {
|
|
|
144
158
|
})
|
|
145
159
|
}
|
|
146
160
|
|
|
161
|
+
/*
|
|
162
|
+
* Get the meta repo path for the current user
|
|
163
|
+
* The meta repo contains a JSON file which contains the list of websites
|
|
164
|
+
*/
|
|
165
|
+
private getMetaRepoPath(session: GitlabSession): string {
|
|
166
|
+
if(!session.gitlab?.username) throw new ApiError('Missing Gitlab user ID. User not logged in?', 401)
|
|
167
|
+
return encodeURIComponent(`${session.gitlab.username}/${this.options.metaRepo}`)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Initialize the storage with a meta repo
|
|
172
|
+
*/
|
|
173
|
+
private async initStorage(session: GitlabSession): Promise<void> {
|
|
174
|
+
// Create the meta repo
|
|
175
|
+
try {
|
|
176
|
+
const project = await this.callApi(session, 'api/v4/projects/', 'POST', {
|
|
177
|
+
name: this.options.metaRepo,
|
|
178
|
+
}) as any
|
|
179
|
+
return this.createFile(session, this.getMetaRepoPath(session), this.options.metaRepoFile, JSON.stringify({
|
|
180
|
+
websites: {}
|
|
181
|
+
} as MetaRepoFileContent))
|
|
182
|
+
} catch (e) {
|
|
183
|
+
console.error('Could not init storage', e.statusCode, e.httpStatusCode, e)
|
|
184
|
+
throw e
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Call the Gitlab API with the user's token and handle errors
|
|
190
|
+
*/
|
|
147
191
|
private async callApi(session: GitlabSession, path: string, method: 'POST' | 'GET' | 'PUT' | 'DELETE' = 'GET', body: GitlabWriteFile | GitlabGetToken | GitlabWebsiteName | GitlabCreateBranch | null = null, params: any = {}): Promise<any> {
|
|
148
192
|
const token = session?.gitlab?.token
|
|
149
193
|
const tokenParam = token ? `access_token=${token.access_token}&` : ''
|
|
@@ -167,7 +211,7 @@ export default class GitlabConnector implements StorageConnector {
|
|
|
167
211
|
throw e
|
|
168
212
|
} else {
|
|
169
213
|
// Useless error linked to the fact that the response is not JSON
|
|
170
|
-
|
|
214
|
+
console.error('Gitlab API error (3) - could not parse response', response.status, response.statusText, {url, method, body, params, text})
|
|
171
215
|
return text
|
|
172
216
|
}
|
|
173
217
|
}
|
|
@@ -196,12 +240,14 @@ export default class GitlabConnector implements StorageConnector {
|
|
|
196
240
|
}
|
|
197
241
|
return await this.callApi(session, path, method, body as any, params)
|
|
198
242
|
} else {
|
|
199
|
-
|
|
200
|
-
|
|
243
|
+
const message = typeof refreshJson?.message === 'object' ? Object.entries(refreshJson.message).map(entry => entry.join(' ')).join(' ') : refreshJson?.message ?? refreshJson?.error ?? response.statusText
|
|
244
|
+
console.error('Gitlab API error (2) - could not refresh token', response.status, response.statusText, {message})
|
|
245
|
+
throw new ApiError(`Gitlab API error (2): ${message}`, response.status)
|
|
201
246
|
}
|
|
202
247
|
} else {
|
|
203
|
-
|
|
204
|
-
|
|
248
|
+
const message = typeof json?.message === 'object' ? Object.entries(json.message).map(entry => entry.join(' ')).join(' ') : json?.message ?? json?.error ?? response.statusText
|
|
249
|
+
console.error('Gitlab API error (1)', response.status, response.statusText, {message})
|
|
250
|
+
throw new ApiError(`Gitlab API error (1): ${message}`, response.status)
|
|
205
251
|
}
|
|
206
252
|
}
|
|
207
253
|
return json
|
|
@@ -281,7 +327,7 @@ export default class GitlabConnector implements StorageConnector {
|
|
|
281
327
|
if(!session.gitlab?.codeVerifier) throw new ApiError('Missing code verifier', 401)
|
|
282
328
|
if(!session.gitlab?.codeChallenge) throw new ApiError('Missing code challenge', 401)
|
|
283
329
|
|
|
284
|
-
const
|
|
330
|
+
const response = await fetch('https://gitlab.com/oauth/token', {
|
|
285
331
|
method: 'POST',
|
|
286
332
|
headers: {
|
|
287
333
|
'Content-Type': 'application/json',
|
|
@@ -295,13 +341,16 @@ export default class GitlabConnector implements StorageConnector {
|
|
|
295
341
|
code_verifier: session.gitlab.codeVerifier,
|
|
296
342
|
}),
|
|
297
343
|
})
|
|
298
|
-
.then((response) => response.json())
|
|
299
344
|
|
|
345
|
+
const token = await response.json()
|
|
346
|
+
|
|
347
|
+
// Store the token in the session
|
|
300
348
|
session.gitlab = { token, state: session.gitlab.state, codeVerifier: session.gitlab.codeVerifier, codeChallenge: session.gitlab.codeChallenge }
|
|
301
349
|
|
|
302
350
|
// We need to get the user ID for listWebsites
|
|
303
351
|
const user = await this.callApi(session, 'api/v4/user') as any
|
|
304
352
|
session.gitlab.userId = user.id
|
|
353
|
+
session.gitlab.username = user.username
|
|
305
354
|
}
|
|
306
355
|
|
|
307
356
|
async logout(session: GitlabSession): Promise<void> {
|
|
@@ -313,19 +362,42 @@ export default class GitlabConnector implements StorageConnector {
|
|
|
313
362
|
return {
|
|
314
363
|
name: user.name,
|
|
315
364
|
email: user.email,
|
|
365
|
+
picture: user.avatar_url,
|
|
316
366
|
storage: await toConnectorData(session, this as StorageConnector),
|
|
317
367
|
}
|
|
318
368
|
}
|
|
319
369
|
|
|
320
370
|
async listWebsites(session: GitlabSession): Promise<WebsiteMeta[]> {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
371
|
+
try {
|
|
372
|
+
const result = await this.callApi(session, `api/v4/projects/${this.getMetaRepoPath(session)}/repository/files/${this.options.metaRepoFile}`, 'GET', null, {
|
|
373
|
+
ref: this.options.branch,
|
|
374
|
+
})
|
|
375
|
+
const { content } = result
|
|
376
|
+
const contentDecoded = Buffer.from(content, 'base64').toString('utf8')
|
|
377
|
+
const websites = (JSON.parse(contentDecoded) as MetaRepoFileContent).websites
|
|
378
|
+
return Object.entries(websites).map(([websiteId, {meta, createdAt, updatedAt}]) => ({
|
|
379
|
+
websiteId,
|
|
380
|
+
createdAt: new Date(createdAt),
|
|
381
|
+
updatedAt: new Date(updatedAt),
|
|
382
|
+
...meta,
|
|
383
|
+
}))
|
|
384
|
+
} catch (e) {
|
|
385
|
+
console.error('Could not list websites', e.statusCode, e.httpStatusCode, e.code)
|
|
386
|
+
if (e.statusCode === 404 || e.httpStatusCode === 404) {
|
|
387
|
+
await this.initStorage(session)
|
|
388
|
+
return []
|
|
389
|
+
} else {
|
|
390
|
+
throw e
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
//const projects = await this.callApi(session, `api/v4/users/${session.gitlab?.user?.id}/projects`) as any[]
|
|
394
|
+
//return projects.map(p => ({
|
|
395
|
+
// websiteId: p.id,
|
|
396
|
+
// name: p.name,
|
|
397
|
+
// createdAt: p.created_at,
|
|
398
|
+
// updatedAt: p.last_activity_at,
|
|
399
|
+
// connectorUserSettings: {},
|
|
400
|
+
//}))
|
|
329
401
|
}
|
|
330
402
|
|
|
331
403
|
async readWebsite(session: GitlabSession, websiteId: string): Promise<WebsiteData> {
|
|
@@ -343,9 +415,9 @@ export default class GitlabConnector implements StorageConnector {
|
|
|
343
415
|
name: websiteMeta.name,
|
|
344
416
|
}) as any
|
|
345
417
|
await this.createFile(session, project.id, WEBSITE_DATA_FILE, JSON.stringify({} as WebsiteData))
|
|
346
|
-
await this.createFile(session, project.id, WEBSITE_META_DATA_FILE, JSON.stringify(websiteMeta))
|
|
418
|
+
//await this.createFile(session, project.id, WEBSITE_META_DATA_FILE, JSON.stringify(websiteMeta))
|
|
347
419
|
//await this.updateWebsite(session, project.id, {} as WebsiteData)
|
|
348
|
-
|
|
420
|
+
await this.setWebsiteMeta(session, project.id, websiteMeta)
|
|
349
421
|
return project.id
|
|
350
422
|
}
|
|
351
423
|
|
|
@@ -360,28 +432,75 @@ export default class GitlabConnector implements StorageConnector {
|
|
|
360
432
|
}
|
|
361
433
|
|
|
362
434
|
async deleteWebsite(session: GitlabSession, websiteId: WebsiteId): Promise<void> {
|
|
435
|
+
// Delete repo
|
|
363
436
|
await this.callApi(session, `api/v4/projects/${websiteId}`, 'DELETE')
|
|
437
|
+
// Load the meta repo data
|
|
438
|
+
const file = await this.callApi(session, `api/v4/projects/${this.getMetaRepoPath(session)}/repository/files/${this.options.metaRepoFile}`, 'GET', null, {
|
|
439
|
+
ref: this.options.branch,
|
|
440
|
+
})
|
|
441
|
+
const metaRepo = JSON.parse(Buffer.from(file.content, 'base64').toString('utf8')) as MetaRepoFileContent
|
|
442
|
+
const data = metaRepo.websites[websiteId]
|
|
443
|
+
if(!data) throw new ApiError(`Website ${websiteId} not found`, 404)
|
|
444
|
+
// Update or create the website meta data
|
|
445
|
+
delete metaRepo.websites[websiteId]
|
|
446
|
+
// Save the meta repo data
|
|
447
|
+
const project = await this.callApi(session, `api/v4/projects/${this.getMetaRepoPath(session)}/repository/files/${this.options.metaRepoFile}`, 'PUT', {
|
|
448
|
+
branch: this.options.branch,
|
|
449
|
+
commit_message: `Delete meta data of ${data.meta.name} (${websiteId}) from Silex`,
|
|
450
|
+
content: JSON.stringify(metaRepo),
|
|
451
|
+
file_path: this.options.metaRepoFile,
|
|
452
|
+
})
|
|
364
453
|
}
|
|
365
454
|
|
|
366
455
|
async getWebsiteMeta(session: GitlabSession, websiteId: WebsiteId): Promise<WebsiteMeta> {
|
|
367
|
-
const
|
|
456
|
+
const file = await this.callApi(session, `api/v4/projects/${this.getMetaRepoPath(session)}/repository/files/${this.options.metaRepoFile}`, 'GET', null, {
|
|
457
|
+
ref: this.options.branch,
|
|
458
|
+
})
|
|
459
|
+
const metaRepo = JSON.parse(Buffer.from(file.content, 'base64').toString('utf8')) as MetaRepoFileContent
|
|
460
|
+
if(!metaRepo.websites[websiteId]) throw new ApiError(`Website ${websiteId} not found`, 404)
|
|
368
461
|
return {
|
|
369
|
-
websiteId
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
connectorUserSettings: {},
|
|
462
|
+
websiteId,
|
|
463
|
+
createdAt: new Date(metaRepo.websites[websiteId].createdAt),
|
|
464
|
+
updatedAt: new Date(metaRepo.websites[websiteId].updatedAt),
|
|
465
|
+
...metaRepo.websites[websiteId].meta,
|
|
374
466
|
}
|
|
467
|
+
//const project = await this.callApi(session, `api/v4/projects/${websiteId}/repository/files/${WEBSITE_META_DATA_FILE}`) as any
|
|
468
|
+
//return {
|
|
469
|
+
// websiteId: project.id,
|
|
470
|
+
// name: project.name,
|
|
471
|
+
// createdAt: project.created_at,
|
|
472
|
+
// updatedAt: project.last_activity_at,
|
|
473
|
+
// connectorUserSettings: {},
|
|
474
|
+
//}
|
|
375
475
|
}
|
|
376
476
|
|
|
377
477
|
async setWebsiteMeta(session: GitlabSession, websiteId: WebsiteId, websiteMeta: WebsiteMetaFileContent): Promise<void> {
|
|
378
|
-
|
|
478
|
+
// Load the meta repo data
|
|
479
|
+
const file = await this.callApi(session, `api/v4/projects/${this.getMetaRepoPath(session)}/repository/files/${this.options.metaRepoFile}`, 'GET', null, {
|
|
480
|
+
ref: this.options.branch,
|
|
481
|
+
})
|
|
482
|
+
const metaRepo = JSON.parse(Buffer.from(file.content, 'base64').toString('utf8')) as MetaRepoFileContent
|
|
483
|
+
// Update or create the website meta data
|
|
484
|
+
metaRepo.websites[websiteId] = {
|
|
485
|
+
updatedAt: new Date().toISOString(),
|
|
486
|
+
createdAt: metaRepo.websites[websiteId]?.createdAt ?? new Date().toISOString(),
|
|
487
|
+
meta: websiteMeta,
|
|
488
|
+
}
|
|
489
|
+
// Save the meta repo data
|
|
490
|
+
const project = await this.callApi(session, `api/v4/projects/${this.getMetaRepoPath(session)}/repository/files/${this.options.metaRepoFile}`, 'PUT', {
|
|
379
491
|
branch: this.options.branch,
|
|
380
|
-
commit_message:
|
|
381
|
-
content: JSON.stringify(
|
|
382
|
-
file_path:
|
|
383
|
-
id: websiteId,
|
|
492
|
+
commit_message: `Update website meta data of ${websiteMeta.name} (${websiteId}) from Silex`,
|
|
493
|
+
content: JSON.stringify(metaRepo),
|
|
494
|
+
file_path: this.options.metaRepoFile,
|
|
384
495
|
})
|
|
496
|
+
|
|
497
|
+
//const project = await this.callApi(session, `api/v4/projects/${websiteId}/repository/files/${WEBSITE_META_DATA_FILE}`, 'PUT', {
|
|
498
|
+
// branch: this.options.branch,
|
|
499
|
+
// commit_message: 'Update website meta data from Silex',
|
|
500
|
+
// content: JSON.stringify(websiteMeta),
|
|
501
|
+
// file_path: WEBSITE_META_DATA_FILE,
|
|
502
|
+
// id: websiteId,
|
|
503
|
+
//})
|
|
385
504
|
}
|
|
386
505
|
|
|
387
506
|
async writeAssets(session: GitlabSession, websiteId: string, files: ConnectorFile[], status?: StatusCallback | undefined): Promise<void> {
|
|
@@ -393,8 +512,8 @@ export default class GitlabConnector implements StorageConnector {
|
|
|
393
512
|
await this.updateFile(session, websiteId, this.getAssetPath(file.path), content, true)
|
|
394
513
|
} catch (e) {
|
|
395
514
|
// If the file does not exist, create it
|
|
396
|
-
if (e.statusCode === 404 || e.message.endsWith('A file with this name doesn\'t exist')) {
|
|
397
|
-
await this.createFile(session, websiteId, file.path, content, true)
|
|
515
|
+
if (e.statusCode === 404 || e.httpStatusCode === 404 || e.message.endsWith('A file with this name doesn\'t exist')) {
|
|
516
|
+
await this.createFile(session, websiteId, this.getAssetPath(file.path), content, true)
|
|
398
517
|
} else {
|
|
399
518
|
throw e
|
|
400
519
|
}
|
|
@@ -417,6 +536,7 @@ export default class GitlabConnector implements StorageConnector {
|
|
|
417
536
|
if(!response.ok) throw new ApiError(`Gitlab API error: ${json?.message ?? json?.error ?? response.statusText}`, response.status)
|
|
418
537
|
// From base64 string to buffer
|
|
419
538
|
const buf = Buffer.from(json.content, 'base64')
|
|
539
|
+
// Return the image bytes
|
|
420
540
|
return buf
|
|
421
541
|
}
|
|
422
542
|
|
|
@@ -47,18 +47,18 @@ export default async function(config, opts = {}) {
|
|
|
47
47
|
// SSL
|
|
48
48
|
// force ssl if the env var SILEX_FORCE_HTTPS is set
|
|
49
49
|
if (options.forceHttps) {
|
|
50
|
-
console.
|
|
50
|
+
console.info('> [SslPlugin] Force SSL option is enabled')
|
|
51
51
|
app.set('forceSSLOptions', {
|
|
52
52
|
trustXFPHeader: !!options.trustXFPHeader,
|
|
53
53
|
})
|
|
54
54
|
router.use(forceSSL)
|
|
55
55
|
} else {
|
|
56
|
-
console.
|
|
56
|
+
console.info('> [SslPlugin] Force SSL option is disabled, env var SILEX_FORCE_HTTPS not set')
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
// SSL certificate
|
|
60
60
|
if (options.privateKey && options.certificate) {
|
|
61
|
-
console.
|
|
61
|
+
console.info('> [SslPlugin] SSL certificate is enabled, found certificate:', options.certificate)
|
|
62
62
|
try {
|
|
63
63
|
const privateKey = readFileSync(options.privateKey).toString()
|
|
64
64
|
const certificate = readFileSync(options.certificate).toString()
|
|
@@ -71,13 +71,13 @@ export default async function(config, opts = {}) {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
createServer(sslServerOptions, this).listen(options.sslPort, () => {
|
|
74
|
-
console.
|
|
74
|
+
console.info('> [SslPlugin] Listening on port ', options.sslPort)
|
|
75
75
|
})
|
|
76
76
|
} catch (e) {
|
|
77
77
|
console.error('> [SslPlugin] Load certificate failed.', e)
|
|
78
78
|
}
|
|
79
79
|
} else {
|
|
80
|
-
console.
|
|
80
|
+
console.info('> [SslPlugin] Certificate disabled, env vars SILEX_SSL_CERTIFICATE and SILEX_SSL_PRIVATE_KEY not set')
|
|
81
81
|
}
|
|
82
82
|
app.use(router)
|
|
83
83
|
})
|
|
@@ -48,6 +48,9 @@ export default async function(config, opts = {}) {
|
|
|
48
48
|
}, {
|
|
49
49
|
route: '/',
|
|
50
50
|
path: join(__dirname, '../../../../..', 'dist', 'client'),
|
|
51
|
+
}, {
|
|
52
|
+
route: '/',
|
|
53
|
+
path: join(__dirname, '../../../../..', 'dist', 'plugins', 'client'),
|
|
51
54
|
},
|
|
52
55
|
]
|
|
53
56
|
// add project route for source maps
|
|
@@ -57,6 +60,7 @@ export default async function(config, opts = {}) {
|
|
|
57
60
|
}] : []),
|
|
58
61
|
...opts,
|
|
59
62
|
}
|
|
63
|
+
console.info('> [StaticPlugin] Serving static files')
|
|
60
64
|
|
|
61
65
|
config.on(ServerEvent.STARTUP_START, ({app}) => {
|
|
62
66
|
const router = express.Router()
|
package/src/ts/server/config.ts
CHANGED
|
@@ -103,7 +103,7 @@ export class ServerConfig extends Config {
|
|
|
103
103
|
async addRoutes(app: Application) {
|
|
104
104
|
const path = process.env.SILEX_CLIENT_CONFIG
|
|
105
105
|
if (path) {
|
|
106
|
-
console.
|
|
106
|
+
console.info(`> Serving client side config ${path} at ${CLIENT_CONFIG_FILE_NAME}`)
|
|
107
107
|
try {
|
|
108
108
|
// Load the client config file
|
|
109
109
|
let clientConfig = (await readFile(path as string)).toString()
|
|
@@ -111,7 +111,7 @@ export class ServerConfig extends Config {
|
|
|
111
111
|
app.get(`/${CLIENT_CONFIG_FILE_NAME}`, async (req: Request, res: Response) => {
|
|
112
112
|
// Reload each time in debug mode
|
|
113
113
|
if (this.debug) {
|
|
114
|
-
console.
|
|
114
|
+
console.info('[Debug mode] Reloading config file', path)
|
|
115
115
|
clientConfig = (await readFile(path)).toString()
|
|
116
116
|
}
|
|
117
117
|
// Send the config file
|
|
@@ -143,7 +143,7 @@ export class ServerConfig extends Config {
|
|
|
143
143
|
*/
|
|
144
144
|
async loadUserConfig() {
|
|
145
145
|
if (this.userConfigPath) {
|
|
146
|
-
console.
|
|
146
|
+
console.info('> Loading user config', this.userConfigPath)
|
|
147
147
|
try {
|
|
148
148
|
// Initiate the process with the config file which is just another plugin
|
|
149
149
|
await this.addPlugin(this.userConfigPath, {})
|
|
@@ -158,12 +158,11 @@ export class ServerConfig extends Config {
|
|
|
158
158
|
* This is the main config file
|
|
159
159
|
*/
|
|
160
160
|
async loadSilexConfig() {
|
|
161
|
-
console.
|
|
161
|
+
console.info('> Loading config', this.configFilePath)
|
|
162
162
|
try {
|
|
163
163
|
// Initiate the process with the config file which is just another plugin
|
|
164
164
|
await this.addPlugin(this.configFilePath, {})
|
|
165
165
|
} catch(e) {
|
|
166
|
-
console.log(e.requireStack[0])
|
|
167
166
|
// Check if the error is about the config file not found and not another module not found in the config file
|
|
168
167
|
if(e.code === 'MODULE_NOT_FOUND' && (!e.requireStack || !e.requireStack.find(path => path === this.configFilePath))) {
|
|
169
168
|
console.info('> /!\\ Config file not found', this.configFilePath)
|
|
@@ -32,7 +32,7 @@ import { fileURLToPath } from 'url'
|
|
|
32
32
|
if(!globalThis.__dirname) {
|
|
33
33
|
// @ts-ignore
|
|
34
34
|
globalThis.__dirname = dirname(process.cwd() + '/src/ts/server/connectors/FsStorage.ts')
|
|
35
|
-
console.
|
|
35
|
+
console.info('Redefining __dirname', globalThis.__dirname)
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
type FsSession = ConnectorSession
|
package/src/ts/server/express.ts
CHANGED
|
@@ -33,7 +33,7 @@ export function create(config: ServerConfig): Application {
|
|
|
33
33
|
// CORS
|
|
34
34
|
const options = config.expressOptions
|
|
35
35
|
if (options.cors) {
|
|
36
|
-
console.
|
|
36
|
+
console.info('> CORS are ENABLED:', options.cors)
|
|
37
37
|
app.use(cors({
|
|
38
38
|
origin: options.cors,
|
|
39
39
|
}))
|
|
@@ -45,7 +45,7 @@ export function create(config: ServerConfig): Application {
|
|
|
45
45
|
app.use(bodyParser.json({ limit: options.jsonLimit }))
|
|
46
46
|
app.use(bodyParser.text({ limit: options.textLimit }))
|
|
47
47
|
app.use(bodyParser.urlencoded({ limit: options.urlencodedLimit }))
|
|
48
|
-
console.
|
|
48
|
+
console.info('> Session name:', options.sessionName)
|
|
49
49
|
app.use(cookieParser() as any)
|
|
50
50
|
app.use(session({
|
|
51
51
|
name: options.sessionName,
|
package/src/ts/types.ts
CHANGED
|
@@ -61,7 +61,7 @@ export type ApiWebsiteCreateBody = WebsiteMetaFileContent
|
|
|
61
61
|
export type ApiWebsiteCreateResponse = { message: string }
|
|
62
62
|
export type ApiWebsiteDeleteQuery = { websiteId: WebsiteId, connectorId?: ConnectorId }
|
|
63
63
|
export type ApiWebsiteMetaReadQuery = { websiteId: WebsiteId, connectorId?: ConnectorId }
|
|
64
|
-
export type ApiWebsiteMetaReadResponse =
|
|
64
|
+
export type ApiWebsiteMetaReadResponse = WebsiteMeta
|
|
65
65
|
export type ApiWebsiteMetaWriteQuery = { websiteId: WebsiteId, connectorId?: ConnectorId }
|
|
66
66
|
export type ApiWebsiteMetaWriteBody = WebsiteMetaFileContent
|
|
67
67
|
export type ApiWebsiteMetaWriteResponse = { message: string }
|