@appsemble/node-utils 0.35.20 → 0.36.1
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/README.md +3 -3
- package/app.js +3 -1
- package/middleware/frontend.js +1 -1
- package/package.json +10 -10
- package/readAsset.d.ts +1 -1
- package/server/routes/appRouter/index.js +5 -0
- package/server/routes/appRouter/indexHandler.js +6 -0
- package/server/routes/appRouter/securityHandler.d.ts +3 -0
- package/server/routes/appRouter/securityHandler.js +11 -0
- package/server/types.d.ts +9 -1
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
#  Appsemble Node Utilities
|
|
2
2
|
|
|
3
3
|
> NodeJS utilities used by Appsemble internally.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@appsemble/node-utils)
|
|
6
|
-
[](https://gitlab.com/appsemble/appsemble/-/releases/0.36.1)
|
|
7
7
|
[](https://prettier.io)
|
|
8
8
|
|
|
9
9
|
## Table of Contents
|
|
@@ -26,5 +26,5 @@ compatibility is not guaranteed.
|
|
|
26
26
|
|
|
27
27
|
## License
|
|
28
28
|
|
|
29
|
-
[LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.
|
|
29
|
+
[LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.36.1/LICENSE.md) ©
|
|
30
30
|
[Appsemble](https://appsemble.com)
|
package/app.js
CHANGED
|
@@ -26,7 +26,7 @@ const getPluralRules = memoize((locale, opts) => new Intl.PluralRules(locale, op
|
|
|
26
26
|
* @returns A localized remapper context for the app.
|
|
27
27
|
*/
|
|
28
28
|
export async function getRemapperContext(app, language, options, context) {
|
|
29
|
-
const { getAppMessages, getAppUrl, getAppVariables, getCurrentAppMember } = options;
|
|
29
|
+
const { getAppMessages, getAppUrl, getAppVariables, getCurrentAppMember, getCurrentAppMemberSelectedGroup, } = options;
|
|
30
30
|
const appUrl = String(await getAppUrl({ context, app }));
|
|
31
31
|
const appMessages = await getAppMessages({
|
|
32
32
|
app,
|
|
@@ -35,6 +35,7 @@ export async function getRemapperContext(app, language, options, context) {
|
|
|
35
35
|
});
|
|
36
36
|
const appVariables = await getAppVariables({ context, app });
|
|
37
37
|
const appMemberInfo = await getCurrentAppMember({ context, app });
|
|
38
|
+
const groupInfo = await getCurrentAppMemberSelectedGroup({ context, app });
|
|
38
39
|
const cache = objectCache((message) => new IntlMessageFormat(message, language, undefined, {
|
|
39
40
|
formatters: {
|
|
40
41
|
// XXX: idk
|
|
@@ -64,6 +65,7 @@ export async function getRemapperContext(app, language, options, context) {
|
|
|
64
65
|
appMemberInfo,
|
|
65
66
|
context: {},
|
|
66
67
|
locale: appMemberInfo?.locale ?? app.definition.defaultLanguage ?? defaultLocale,
|
|
68
|
+
group: groupInfo ?? undefined,
|
|
67
69
|
};
|
|
68
70
|
}
|
|
69
71
|
function replaceStyle(stylesheet, selector, property, value) {
|
package/middleware/frontend.js
CHANGED
|
@@ -8,7 +8,7 @@ import webpackDevMiddleware from 'webpack-dev-middleware';
|
|
|
8
8
|
*/
|
|
9
9
|
const skipRoute = /^\/(api|oauth2\/token)/;
|
|
10
10
|
export async function frontend(webpackConfigs, argv, serveStudio = false) {
|
|
11
|
-
// eslint-disable-next-line @typescript-eslint/
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
12
12
|
// @ts-ignore Because the webpack core config isn’t built when building the server, an error is
|
|
13
13
|
// expected here at build time, but while type checking.
|
|
14
14
|
const { createAppConfig, createStudioConfig } = await import('@appsemble/webpack-core');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appsemble/node-utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.36.1",
|
|
4
4
|
"description": "NodeJS utilities used by Appsemble internally.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"app",
|
|
@@ -40,9 +40,10 @@
|
|
|
40
40
|
"test": "vitest"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@appsemble/lang-sdk": "0.
|
|
44
|
-
"@appsemble/types": "0.
|
|
45
|
-
"@appsemble/utils": "0.
|
|
43
|
+
"@appsemble/lang-sdk": "0.36.1",
|
|
44
|
+
"@appsemble/types": "0.36.1",
|
|
45
|
+
"@appsemble/utils": "0.36.1",
|
|
46
|
+
"@appsemble/webpack-core": "0.36.1",
|
|
46
47
|
"@formatjs/fast-memoize": "^2.0.0",
|
|
47
48
|
"@fortawesome/fontawesome-free": "^6.0.0",
|
|
48
49
|
"@kubernetes/client-node": "^0.22.2",
|
|
@@ -65,14 +66,12 @@
|
|
|
65
66
|
"form-data": "^4.0.4",
|
|
66
67
|
"fs-extra": "^11.0.0",
|
|
67
68
|
"inquirer": "^9.0.0",
|
|
68
|
-
"intl-messageformat": "^
|
|
69
|
+
"intl-messageformat": "^11.0.0",
|
|
69
70
|
"jsonschema": "~1.4.1",
|
|
70
71
|
"keytar": "^7.0.0",
|
|
71
72
|
"koa": "^2.0.0",
|
|
72
73
|
"koa-compose": "^4.0.0",
|
|
73
|
-
"koa-compress": "^5.1.1",
|
|
74
74
|
"koa-mount": "^4.0.0",
|
|
75
|
-
"koa-range": "^0.3.0",
|
|
76
75
|
"koa-static": "^5.0.0",
|
|
77
76
|
"koas-body-parser": "^0.7.0",
|
|
78
77
|
"koas-core": "^0.7.0",
|
|
@@ -106,9 +105,10 @@
|
|
|
106
105
|
},
|
|
107
106
|
"devDependencies": {
|
|
108
107
|
"@types/busboy": "1.5.4",
|
|
109
|
-
"@types/css-tree": "2.3.
|
|
110
|
-
"@types/koa
|
|
111
|
-
"@types/koa-
|
|
108
|
+
"@types/css-tree": "2.3.11",
|
|
109
|
+
"@types/express-to-koa": "1.0.4",
|
|
110
|
+
"@types/koa-mount": "4.0.5",
|
|
111
|
+
"@types/mustache": "4.2.5",
|
|
112
112
|
"@types/type-is": "1.6.7",
|
|
113
113
|
"@types/uuid": "10.0.0",
|
|
114
114
|
"axios-mock-adapter": "1.22.0",
|
package/readAsset.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { createManifestHandler } from './manifestHandler.js';
|
|
|
14
14
|
import { createReadmeHandler } from './readmeHandler.js';
|
|
15
15
|
import { createRobotsHandler } from './robotsHandler.js';
|
|
16
16
|
import { createScreenshotHandler } from './screenshotHandler.js';
|
|
17
|
+
import { createSecurityHandler } from './securityHandler.js';
|
|
17
18
|
import { createServiceWorkerHandler } from './serviceWorkerHandler.js';
|
|
18
19
|
import { createStaticHandler } from './staticHandler.js';
|
|
19
20
|
const require = createRequire(import.meta.url);
|
|
@@ -24,6 +25,10 @@ export function createAppRouter(options) {
|
|
|
24
25
|
route: '/manifest.json',
|
|
25
26
|
get: createManifestHandler(options),
|
|
26
27
|
},
|
|
28
|
+
{
|
|
29
|
+
route: '/.well-known/security.txt',
|
|
30
|
+
get: createSecurityHandler(options),
|
|
31
|
+
},
|
|
27
32
|
{
|
|
28
33
|
route: '/robots.txt',
|
|
29
34
|
get: createRobotsHandler(options),
|
|
@@ -10,6 +10,12 @@ export function createIndexHandler({ createSettings, getApp, getAppDetails, getA
|
|
|
10
10
|
return async (ctx) => {
|
|
11
11
|
const { hostname, path } = ctx;
|
|
12
12
|
const host = getHost({ context: ctx });
|
|
13
|
+
// Prevent mime-type sniffing,
|
|
14
|
+
// Visit https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Content-Type-Options to know more.
|
|
15
|
+
ctx.set('x-content-type-options', 'nosniff');
|
|
16
|
+
// Less strict due to the OAuth mechanism
|
|
17
|
+
// Visit https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Referrer-Policy to know more.
|
|
18
|
+
ctx.set('Referrer-Policy', 'strict-origin-when-cross-origin');
|
|
13
19
|
// Most of the fields here are used either directly or indirectly that's why no attributes query
|
|
14
20
|
const app = await getApp({ context: ctx });
|
|
15
21
|
if (!app) {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { addDays } from 'date-fns';
|
|
2
|
+
import { assertKoaCondition } from '../../../index.js';
|
|
3
|
+
export function createSecurityHandler({ getApp }) {
|
|
4
|
+
return async (ctx) => {
|
|
5
|
+
const app = await getApp({ context: ctx, query: { attributes: ['id', 'updated'] } });
|
|
6
|
+
assertKoaCondition(app != null, ctx, 404, 'App not found');
|
|
7
|
+
const expires = addDays(new Date(app.$updated ?? app.$created), 180);
|
|
8
|
+
ctx.body = `Contact: mailto:security@appsemble.com\nExpires: ${expires}`;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=securityHandler.js.map
|
package/server/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Readable } from 'node:stream';
|
|
2
|
-
import { type BlockDefinition, type ControllerDefinition, type CustomAppPermission, type EmailActionDefinition, type IdentifiableBlock, type ResourceDefinition, type Theme as ThemeType } from '@appsemble/lang-sdk';
|
|
2
|
+
import { type AppMemberGroup, type BlockDefinition, type ControllerDefinition, type CustomAppPermission, type EmailActionDefinition, type IdentifiableBlock, type ResourceDefinition, type Theme as ThemeType } from '@appsemble/lang-sdk';
|
|
3
3
|
import { type App, type AppConfigEntry, type AppMemberInfo, type AppMessages, type Asset, type BlockManifest, type Group, type OrganizationPermission, type Resource } from '@appsemble/types';
|
|
4
4
|
import { type RawAxiosRequestConfig } from 'axios';
|
|
5
5
|
import { type DefaultContext as DefaultContextInterface, type DefaultState, type ParameterizedContext } from 'koa';
|
|
@@ -115,6 +115,9 @@ declare module 'koas-parameters' {
|
|
|
115
115
|
selectedGroupId: number;
|
|
116
116
|
$own: boolean;
|
|
117
117
|
delimiter?: string;
|
|
118
|
+
email: string;
|
|
119
|
+
width?: number;
|
|
120
|
+
height?: number;
|
|
118
121
|
}
|
|
119
122
|
}
|
|
120
123
|
export type Operator = 'and' | 'not' | 'or';
|
|
@@ -217,6 +220,10 @@ export interface GetCurrentAppMemberParams {
|
|
|
217
220
|
context: ParameterizedContext<DefaultState, DefaultContextInterface, any>;
|
|
218
221
|
app: App;
|
|
219
222
|
}
|
|
223
|
+
export interface GetCurrentAppMemberSelectedGroupParams {
|
|
224
|
+
context: ParameterizedContext<DefaultState, DefaultContextInterface, any>;
|
|
225
|
+
app: App;
|
|
226
|
+
}
|
|
220
227
|
export interface GetCurrentAppMemberGroupsParams {
|
|
221
228
|
context: ParameterizedContext<DefaultState, DefaultContextInterface, any>;
|
|
222
229
|
app: App;
|
|
@@ -367,6 +374,7 @@ export interface ParsedQuery {
|
|
|
367
374
|
export type ContentSecurityPolicy = Record<string, (string | false)[]>;
|
|
368
375
|
export interface Options {
|
|
369
376
|
getCurrentAppMember: (params: GetCurrentAppMemberParams) => Promise<AppMemberInfo | null>;
|
|
377
|
+
getCurrentAppMemberSelectedGroup: (params: GetCurrentAppMemberSelectedGroupParams) => Promise<AppMemberGroup | null>;
|
|
370
378
|
getCurrentAppMemberGroups: (params: GetCurrentAppMemberGroupsParams) => Promise<Group[] | null>;
|
|
371
379
|
getApp: (params: GetAppParams) => Promise<App>;
|
|
372
380
|
getAppDetails: (params: GetAppParams) => Promise<AppDetails>;
|