@ti-engine/web-framework 1.19.1 → 1.20.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 +22 -0
- package/bin/web-app-manager.js +3 -6
- package/bin/web-server.js +8 -9
- package/components/admin-config-handlers.js +3 -0
- package/components/auth-manager.js +3 -7
- package/components/authorization.js +2 -2
- package/components/config-change-notifier.js +4 -4
- package/components/config-registry.js +3 -6
- package/components/config-service.js +9 -6
- package/components/config-store.js +1 -3
- package/components/definitions.types.js +5 -3
- package/components/session-store.js +9 -6
- package/components/user.js +2 -0
- package/components/web-handlers.js +7 -4
- package/package.json +84 -21
- package/types/bin/web-app-manager.d.ts +194 -0
- package/types/bin/web-server.d.ts +373 -0
- package/types/components/admin-config-handlers.d.ts +11 -0
- package/types/components/auth-manager.d.ts +125 -0
- package/types/components/authorization.d.ts +54 -0
- package/types/components/config-change-notifier.d.ts +73 -0
- package/types/components/config-registry.d.ts +149 -0
- package/types/components/config-service.d.ts +218 -0
- package/types/components/config-store.d.ts +128 -0
- package/types/components/definitions.types.d.ts +31 -0
- package/types/components/session-store.d.ts +56 -0
- package/types/components/user.d.ts +83 -0
- package/types/components/web-config-env.d.ts +17 -0
- package/types/components/web-handlers.d.ts +23 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
export = TiWebAppManager;
|
|
2
|
+
import type { TiSession } from "#definitions";
|
|
3
|
+
/**
|
|
4
|
+
* Gates the login-page authentication markup to the effective enabled methods. The login fragment delimits blocks
|
|
5
|
+
* with HTML-comment markers: `<!--ti-auth-method:METHOD-->…<!--/ti-auth-method-->` around each method's control
|
|
6
|
+
* (the `local` credentials form and each OpenID provider button), `<!--ti-auth-divider-->…<!--/ti-auth-divider-->`
|
|
7
|
+
* around the "or continue with" separator, `<!--ti-auth-social-->…<!--/ti-auth-social-->` around the SSO button
|
|
8
|
+
* group, and `<!--ti-auth-none-->…<!--/ti-auth-none-->` around a "no method configured" fallback. It removes the
|
|
9
|
+
* block for any method that is not enabled, drops the social group when no SSO provider is enabled, shows the
|
|
10
|
+
* divider only when a local form AND at least one SSO provider are both present, and shows the fallback only when
|
|
11
|
+
* nothing is enabled. Any remaining markers are stripped so clean HTML ships. Fragments without these markers
|
|
12
|
+
* (every non-login fragment) are returned unchanged.
|
|
13
|
+
*
|
|
14
|
+
* @param {string} html
|
|
15
|
+
* @param {string[]} [enabledMethods] The effective enabled authentication methods.
|
|
16
|
+
* @returns {string}
|
|
17
|
+
*/
|
|
18
|
+
declare function applyAuthMethodVisibility(html: string, enabledMethods?: string[]): string;
|
|
19
|
+
/**
|
|
20
|
+
* A generic web application manager that handles the rendering and behavior of web application views. It is designed to be extended by specific web application
|
|
21
|
+
* managers for each web application you want to implement with the ti-engine web framework.
|
|
22
|
+
* <br/>
|
|
23
|
+
* NOTE: You should not instantiate this class directly. Instead, extend it and override the abstract methods as needed. Additionally, you should configure your
|
|
24
|
+
* ti-engine web server 'TiWebApplicationConfig' settings by specifying the 'classPath' that corresponds to your web application manager. The path should be
|
|
25
|
+
* relative to the intended process's working directory.
|
|
26
|
+
*
|
|
27
|
+
* @class TiWebAppManager
|
|
28
|
+
* @abstract
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
declare class TiWebAppManager {
|
|
32
|
+
#private;
|
|
33
|
+
/**
|
|
34
|
+
* @constructor
|
|
35
|
+
* @param {string} identifier The identifier for this web application. Should be unique and recognizable.
|
|
36
|
+
* @throws {TiException.E_GEN_ABSTRACT_CLASS_INIT} If this class is instantiated directly.
|
|
37
|
+
*/
|
|
38
|
+
constructor(identifier: string);
|
|
39
|
+
/**
|
|
40
|
+
* Returns the identifier for this web application.
|
|
41
|
+
*
|
|
42
|
+
* @property
|
|
43
|
+
* @returns {string}
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
get webAppIdentifier(): string;
|
|
47
|
+
/**
|
|
48
|
+
* Adds a new HTML fragment to the web application.
|
|
49
|
+
* <br/>
|
|
50
|
+
* NOTE: This method should only be called during the initialization phase of your web application manager.
|
|
51
|
+
*
|
|
52
|
+
* @method
|
|
53
|
+
* @param {string} identifier
|
|
54
|
+
* @param {Object} fragment The fragment descriptor (`{ title, path, components }`). May also carry an optional
|
|
55
|
+
* `roles` array (`Array<string|number>`): when present, the default {@link TiWebAppManager#verifyAccess} serves
|
|
56
|
+
* the fragment only to sessions holding at least one of those roles; omit it (or leave empty) for a public screen.
|
|
57
|
+
* @throws {TiException.E_GEN_UNALLOWED_OVERRIDE} If a fragment with the same identifier already exists.
|
|
58
|
+
* @public
|
|
59
|
+
*/
|
|
60
|
+
addFragment(identifier: string, fragment: Object): void;
|
|
61
|
+
/**
|
|
62
|
+
* Registers an editable configuration document with the framework config registry (JSON Schema + semantic
|
|
63
|
+
* validators + default value + editor metadata). Call during initialization. See {@link ConfigRegistry#register}.
|
|
64
|
+
*
|
|
65
|
+
* @method
|
|
66
|
+
* @param {string} configKey
|
|
67
|
+
* @param {Object} definition
|
|
68
|
+
* @returns {TiWebAppManager} this (chainable)
|
|
69
|
+
* @public
|
|
70
|
+
*/
|
|
71
|
+
registerConfigDocument(configKey: string, definition: Object): TiWebAppManager;
|
|
72
|
+
/**
|
|
73
|
+
* Registers a JSON Schema that is referenced (via `$ref`) by config-document schemas but is not itself a document.
|
|
74
|
+
*
|
|
75
|
+
* @method
|
|
76
|
+
* @param {Object} schema
|
|
77
|
+
* @returns {TiWebAppManager} this (chainable)
|
|
78
|
+
* @public
|
|
79
|
+
*/
|
|
80
|
+
registerConfigSchema(schema: Object): TiWebAppManager;
|
|
81
|
+
/**
|
|
82
|
+
* Registers a composite (entity) editor with the framework config service — a `compose(docs)`/`decompose(edited,docs)`
|
|
83
|
+
* pair over one or more documents. Call during initialization. See {@link ConfigService#registerEditor}.
|
|
84
|
+
*
|
|
85
|
+
* @method
|
|
86
|
+
* @param {string} editorKey
|
|
87
|
+
* @param {Object} definition
|
|
88
|
+
* @returns {TiWebAppManager} this (chainable)
|
|
89
|
+
* @public
|
|
90
|
+
*/
|
|
91
|
+
registerConfigEditor(editorKey: string, definition: Object): TiWebAppManager;
|
|
92
|
+
/**
|
|
93
|
+
* Used to clear the static file cache. This is useful for testing purposes to ensure that the web server is always serving fresh content.
|
|
94
|
+
*
|
|
95
|
+
* @method
|
|
96
|
+
* @public
|
|
97
|
+
*/
|
|
98
|
+
clearStaticFileCache(): void;
|
|
99
|
+
/**
|
|
100
|
+
* Sets the effective enabled authentication methods used to gate login-page provider buttons. The web server
|
|
101
|
+
* calls this at startup, after the auth manager has dropped any enabled-but-unconfigured OpenID providers.
|
|
102
|
+
*
|
|
103
|
+
* @method
|
|
104
|
+
* @param {string[]} methods
|
|
105
|
+
* @public
|
|
106
|
+
*/
|
|
107
|
+
setEnabledAuthMethods(methods: string[]): void;
|
|
108
|
+
/**
|
|
109
|
+
* Optional HTML transformation hook.
|
|
110
|
+
* <br/>
|
|
111
|
+
* NOTE: Override in subclasses to add nonces or other dynamic data to outgoing HTML.
|
|
112
|
+
*
|
|
113
|
+
* @method
|
|
114
|
+
* @param {string} html
|
|
115
|
+
* @param {Object} [options]
|
|
116
|
+
* @param {string} [options.csrfToken] Optional CSRF token to inject into the HTML.
|
|
117
|
+
* @param {boolean} [options.isHome] Optional flag to indicate whether the requested route is the home page.
|
|
118
|
+
* @param {string} [options.nonce] Optional CSP nonce to inject into inline scripts/styles.
|
|
119
|
+
* @param {string} [options.title] Optional title to replace the placeholder in the HTML.
|
|
120
|
+
* @returns {Promise<string>}
|
|
121
|
+
* @virtual
|
|
122
|
+
* @public
|
|
123
|
+
*/
|
|
124
|
+
transformHtml(html: string, options?: {
|
|
125
|
+
csrfToken?: string;
|
|
126
|
+
isHome?: boolean;
|
|
127
|
+
nonce?: string;
|
|
128
|
+
title?: string;
|
|
129
|
+
}): Promise<string>;
|
|
130
|
+
/**
|
|
131
|
+
* Used to assemble the complete HTML view for the requested route, including nested HTML fragments.
|
|
132
|
+
*
|
|
133
|
+
* @method
|
|
134
|
+
* @param {TiSession} session
|
|
135
|
+
* @param {string[]} staticContentPaths
|
|
136
|
+
* @param {string} route
|
|
137
|
+
* @param {Object} [options]
|
|
138
|
+
* @param {string} [options.csrfToken] Optional CSRF token to inject into the HTML.
|
|
139
|
+
* @param {boolean} [options.isPartial] Optional flag to indicate whether the requested route is a partial load of a fragment.
|
|
140
|
+
* @param {string} [options.view] Optional view name to load within this route.
|
|
141
|
+
* @param {string} [options.nonce] Optional CSP nonce to inject into inline scripts/styles.
|
|
142
|
+
* @returns {Promise<string>}
|
|
143
|
+
* @public
|
|
144
|
+
*/
|
|
145
|
+
assembleHtmlView(session: TiSession, staticContentPaths: string[], route: string, options?: {
|
|
146
|
+
csrfToken?: string;
|
|
147
|
+
isPartial?: boolean;
|
|
148
|
+
view?: string;
|
|
149
|
+
nonce?: string;
|
|
150
|
+
}): Promise<string>;
|
|
151
|
+
/**
|
|
152
|
+
* Used to process a request for a data resource.
|
|
153
|
+
*
|
|
154
|
+
* @method
|
|
155
|
+
* @param {TiSession} session
|
|
156
|
+
* @param {string} view
|
|
157
|
+
* @param {Object} [options]
|
|
158
|
+
* @returns {Promise<Object>}
|
|
159
|
+
* @virtual
|
|
160
|
+
* @public
|
|
161
|
+
*/
|
|
162
|
+
processDataRequest(session: TiSession, view: string, options?: Object): Promise<Object>;
|
|
163
|
+
/**
|
|
164
|
+
* Used to process an application service request.
|
|
165
|
+
*
|
|
166
|
+
* @method
|
|
167
|
+
* @param {TiSession} session
|
|
168
|
+
* @param {string} service
|
|
169
|
+
* @param {Object} params
|
|
170
|
+
* @returns {Promise<Object>}
|
|
171
|
+
* @virtual
|
|
172
|
+
* @public
|
|
173
|
+
*/
|
|
174
|
+
processServiceRequest(session: TiSession, service: string, params: Object): Promise<Object>;
|
|
175
|
+
/**
|
|
176
|
+
* Used to verify whether the current user has access to the requested resource. The default implementation gates
|
|
177
|
+
* HTML fragments by their declared `roles`: a fragment registered via {@link TiWebAppManager#addFragment} with a
|
|
178
|
+
* `roles` array is served only to sessions holding at least one of those roles (see {@link addFragment}); a
|
|
179
|
+
* fragment with no `roles` is public to any authenticated user. This makes role-restricted screens unreachable by
|
|
180
|
+
* direct URL, not merely hidden in the UI. Override in subclasses only to implement additional/alternative checks.
|
|
181
|
+
*
|
|
182
|
+
* @method
|
|
183
|
+
* @virtual
|
|
184
|
+
* @param {TiSession} session
|
|
185
|
+
* @param {Object} resource The fragment descriptor; its optional `resource.roles` lists the roles permitted to load it.
|
|
186
|
+
* @returns {Promise}
|
|
187
|
+
* @exception {TiException.E_SEC_UNAUTHORIZED_ACCESS} (403) When the session holds none of the fragment's required roles.
|
|
188
|
+
* @public
|
|
189
|
+
*/
|
|
190
|
+
verifyAccess(session: TiSession, resource: Object): Promise<any>;
|
|
191
|
+
}
|
|
192
|
+
declare namespace TiWebAppManager {
|
|
193
|
+
export { applyAuthMethodVisibility };
|
|
194
|
+
}
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
export = TiWebServer;
|
|
2
|
+
import ServiceConsumer = require("@ti-engine/core/service-consumer");
|
|
3
|
+
export type NodeServer = import("node:http").Server;
|
|
4
|
+
export type TiWebServiceConfiguration = ServiceConfiguration;
|
|
5
|
+
export type TiWebApplicationConfig = {
|
|
6
|
+
classPath: string;
|
|
7
|
+
};
|
|
8
|
+
export type ApiConfig = {
|
|
9
|
+
endpointEnabled: boolean;
|
|
10
|
+
inventory: ApiInventory;
|
|
11
|
+
requestTimeout: number;
|
|
12
|
+
};
|
|
13
|
+
export type SettingsAuth = {
|
|
14
|
+
enabledMethods: string[];
|
|
15
|
+
local: Object;
|
|
16
|
+
oauth2: {
|
|
17
|
+
azure?: SettingsOAuth2Client;
|
|
18
|
+
google?: SettingsOAuth2Client;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export type SettingsOAuth2Client = {
|
|
22
|
+
clientID?: string;
|
|
23
|
+
clientSecret?: string;
|
|
24
|
+
callbackUrl?: string;
|
|
25
|
+
discoveryUrl?: string;
|
|
26
|
+
isPublic?: boolean;
|
|
27
|
+
tokenEndpointAuthMethod?: TiTokenEndpointAuthMethod;
|
|
28
|
+
};
|
|
29
|
+
export type SettingsStaticCache = {
|
|
30
|
+
/**
|
|
31
|
+
* The `max-age` for `/static` responses, in SECONDS (not a duration string). `0` means every use is revalidated.
|
|
32
|
+
*/
|
|
33
|
+
maxAge: number;
|
|
34
|
+
/**
|
|
35
|
+
* Whether to add `immutable`. Only correct when the `/static` filenames are content-addressed.
|
|
36
|
+
*/
|
|
37
|
+
immutable: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Path prefixes under `/static` that are served long-lived and `immutable` regardless of the two settings above.
|
|
40
|
+
*/
|
|
41
|
+
immutablePaths: string[];
|
|
42
|
+
};
|
|
43
|
+
export type SettingsCookies = {
|
|
44
|
+
secret: string;
|
|
45
|
+
path: string;
|
|
46
|
+
httpOnly: boolean;
|
|
47
|
+
sameSite: "lax" | "strict" | "none";
|
|
48
|
+
maxAge: number;
|
|
49
|
+
};
|
|
50
|
+
export type ApiInventory = Record<string, Record<string, ServiceAddress>>;
|
|
51
|
+
import type { TiAuthMethod, TiTokenEndpointAuthMethod } from "#auth-manager";
|
|
52
|
+
import type { TiSession } from "#definitions";
|
|
53
|
+
import type User from "#user";
|
|
54
|
+
import type TiWebAppManager from "#web-app-manager";
|
|
55
|
+
import type { ServiceAddress, ServiceConfiguration } from "@ti-engine/core/definitions";
|
|
56
|
+
/** @import { TiAuthMethod, TiTokenEndpointAuthMethod } from "#auth-manager" */
|
|
57
|
+
/** @import { TiSession } from "#definitions" */
|
|
58
|
+
/** @import User from "#user" */
|
|
59
|
+
/** @import TiWebAppManager from "#web-app-manager" */
|
|
60
|
+
/** @import { ServiceAddress, ServiceConfiguration } from "@ti-engine/core/definitions" */
|
|
61
|
+
/**
|
|
62
|
+
* Default unprotected static-asset route matchers. The path segments are matched with `(?:[^/]+\/)*` rather than
|
|
63
|
+
* `(?:.+\/)*`: the inner `[^/]+` cannot also consume the "/" delimiter, so the pattern is unambiguous and matches
|
|
64
|
+
* in linear time. The previous `.+` form was ambiguous and backtracked exponentially on hostile request paths such
|
|
65
|
+
* as `/static/a/a/…/a/x` (no trailing extension) — and these matchers run against the raw request path in
|
|
66
|
+
* {@link TiWebServer#isUnprotectedRoute} BEFORE authentication, so that was a pre-auth denial-of-service vector
|
|
67
|
+
* (CodeQL js/redos). The matched language for realistic asset paths is unchanged.
|
|
68
|
+
*
|
|
69
|
+
* @type {RegExp}
|
|
70
|
+
*/
|
|
71
|
+
declare const RE_STATIC_UNPROTECTED: RegExp;
|
|
72
|
+
/**
|
|
73
|
+
* Default unprotected `/.well-known/` route matcher. See {@link RE_STATIC_UNPROTECTED} for the ReDoS rationale.
|
|
74
|
+
*
|
|
75
|
+
* @type {RegExp}
|
|
76
|
+
*/
|
|
77
|
+
declare const RE_WELL_KNOWN_UNPROTECTED: RegExp;
|
|
78
|
+
/**
|
|
79
|
+
* A web server microservice based on the ti-engine.
|
|
80
|
+
* <br/>
|
|
81
|
+
* Note: The web server is fully functional and already comes with all the necessary fundamentals and security features. However, it is designed to be extended
|
|
82
|
+
* with custom logic and functionality to fit your specific needs. Here is a list of methods that you can override to customize the web server behavior:
|
|
83
|
+
* - {@link TiWebServer#defineWebApplicationRoutes} Override this to define custom web application routes. Remember to call the base method if you want to preserve the default behavior as well (recommended).
|
|
84
|
+
* - {@link TiWebServer#defineUnprotectedRoutes} Override this to define unprotected routes. Remember to call the base method if you want to preserve the default behavior as well (recommended).
|
|
85
|
+
* - {@link TiWebServer#verifySession} Override this to implement custom session verification logic.
|
|
86
|
+
*
|
|
87
|
+
* @class TiWebServer
|
|
88
|
+
* @extends ServiceConsumer
|
|
89
|
+
* @public
|
|
90
|
+
*/
|
|
91
|
+
declare class TiWebServer extends ServiceConsumer {
|
|
92
|
+
#private;
|
|
93
|
+
/**
|
|
94
|
+
* @constructor
|
|
95
|
+
* @param {string} serviceDomainName The service domain name for this service instance.
|
|
96
|
+
* @param {TiWebServiceConfiguration} serviceConfig The JSON configuration for this service. Note that the configuration provided will be merged with the default web server configuration, and it will override any conflicting properties.
|
|
97
|
+
* @throws {TiException.E_GEN_JS_INTERNAL_ERROR} If the web application manager cannot be loaded.
|
|
98
|
+
*/
|
|
99
|
+
constructor(serviceDomainName: string, serviceConfig: TiWebServiceConfiguration);
|
|
100
|
+
/**
|
|
101
|
+
* Property returning the service configuration JSON.
|
|
102
|
+
*
|
|
103
|
+
* @property
|
|
104
|
+
* @returns {TiWebServiceConfiguration}
|
|
105
|
+
* @override
|
|
106
|
+
* @public
|
|
107
|
+
*/
|
|
108
|
+
get serviceConfig(): TiWebServiceConfiguration;
|
|
109
|
+
/**
|
|
110
|
+
* Property returning if the web server is currently shutting down.
|
|
111
|
+
*
|
|
112
|
+
* @property
|
|
113
|
+
* @returns {boolean}
|
|
114
|
+
* @public
|
|
115
|
+
*/
|
|
116
|
+
get isShuttingDown(): boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Property returning the list of static content directories.
|
|
119
|
+
*
|
|
120
|
+
* @property
|
|
121
|
+
* @returns {string[]}
|
|
122
|
+
* @public
|
|
123
|
+
*/
|
|
124
|
+
get staticContentPaths(): string[];
|
|
125
|
+
/**
|
|
126
|
+
* Property returning the server URL.
|
|
127
|
+
*
|
|
128
|
+
* @property
|
|
129
|
+
* @returns {string}
|
|
130
|
+
* @public
|
|
131
|
+
*/
|
|
132
|
+
get serverUrl(): string;
|
|
133
|
+
/**
|
|
134
|
+
* Property returning the {@link TiWebAppManager} instance.
|
|
135
|
+
*
|
|
136
|
+
* @property
|
|
137
|
+
* @returns {TiWebAppManager}
|
|
138
|
+
* @public
|
|
139
|
+
*/
|
|
140
|
+
get webAppManager(): TiWebAppManager;
|
|
141
|
+
/**
|
|
142
|
+
* Starts the web server.
|
|
143
|
+
*
|
|
144
|
+
* @method
|
|
145
|
+
* @returns {Promise}
|
|
146
|
+
* @override
|
|
147
|
+
* @public
|
|
148
|
+
*/
|
|
149
|
+
onStart(): Promise<any>;
|
|
150
|
+
/**
|
|
151
|
+
* Shuts down the web server.
|
|
152
|
+
*
|
|
153
|
+
* @method
|
|
154
|
+
* @returns {Promise}
|
|
155
|
+
* @override
|
|
156
|
+
* @public
|
|
157
|
+
*/
|
|
158
|
+
onStop(): Promise<any>;
|
|
159
|
+
/**
|
|
160
|
+
* Used to report health status of the service instance for external monitoring.
|
|
161
|
+
* This is a scheduled job that will be executed at SERVICE_HEALTH_CHECK_INTERVAL time.
|
|
162
|
+
*
|
|
163
|
+
* @method
|
|
164
|
+
* @override
|
|
165
|
+
* @public
|
|
166
|
+
*/
|
|
167
|
+
reportHealthy(): void;
|
|
168
|
+
/**
|
|
169
|
+
* Used to verify the session of a request.
|
|
170
|
+
*
|
|
171
|
+
* @method
|
|
172
|
+
* @param {TiSession} session
|
|
173
|
+
* @returns {boolean}
|
|
174
|
+
* @public
|
|
175
|
+
*/
|
|
176
|
+
verifySession(session: TiSession): boolean;
|
|
177
|
+
/**
|
|
178
|
+
* Hook for the application to augment the freshly-authenticated session (e.g. derive domain roles from an
|
|
179
|
+
* identity store or the org chart). Runs synchronously, once per login, before the framework's additive `admin`
|
|
180
|
+
* role is applied. The default is a no-op. Any test-user role injection is an override of whatever the app derives.
|
|
181
|
+
*
|
|
182
|
+
* @method
|
|
183
|
+
* @virtual
|
|
184
|
+
* @param {TiSession} session
|
|
185
|
+
* @param {Object} [request] Optional Express request object that can be used to read body/cookies/query data.
|
|
186
|
+
* @returns {TiSession}
|
|
187
|
+
* @public
|
|
188
|
+
*/
|
|
189
|
+
augmentSession(session: TiSession, request?: Object): TiSession;
|
|
190
|
+
/**
|
|
191
|
+
* Used to authenticate a user via the specified auth method.
|
|
192
|
+
*
|
|
193
|
+
* @method
|
|
194
|
+
* @param {TiAuthMethod} authMethod
|
|
195
|
+
* @param {Object} [authDetails={}]
|
|
196
|
+
* @returns {Promise}
|
|
197
|
+
* @public
|
|
198
|
+
*/
|
|
199
|
+
authenticate(authMethod: TiAuthMethod, authDetails?: Object): Promise<any>;
|
|
200
|
+
/**
|
|
201
|
+
* Used to set up user authorization according to the specified auth method.
|
|
202
|
+
*
|
|
203
|
+
* @method
|
|
204
|
+
* @param {TiAuthMethod} authMethod
|
|
205
|
+
* @param {URL} currentUrl
|
|
206
|
+
* @param {Object} oidc
|
|
207
|
+
* @returns {Promise<User>}
|
|
208
|
+
* @public
|
|
209
|
+
*/
|
|
210
|
+
authorize(authMethod: TiAuthMethod, currentUrl: URL, oidc: Object): Promise<User>;
|
|
211
|
+
/**
|
|
212
|
+
* Used to get a service mapping if such exists.
|
|
213
|
+
*
|
|
214
|
+
* @method
|
|
215
|
+
* @param {string} serviceVersion
|
|
216
|
+
* @param {string} serviceName
|
|
217
|
+
* @returns {ServiceAddress}
|
|
218
|
+
* @public
|
|
219
|
+
*/
|
|
220
|
+
getServiceAddress(serviceVersion: string, serviceName: string): ServiceAddress;
|
|
221
|
+
/**
|
|
222
|
+
* Used to check if the specified hostname is allowed to access the web server.
|
|
223
|
+
*
|
|
224
|
+
* @method
|
|
225
|
+
* @param {string} hostname
|
|
226
|
+
* @returns {boolean}
|
|
227
|
+
* @public
|
|
228
|
+
*/
|
|
229
|
+
isAllowedHost(hostname: string): boolean;
|
|
230
|
+
/**
|
|
231
|
+
* Used to check if the specified route is unprotected (i.e., does not require authentication). The default unprotected routes are:
|
|
232
|
+
* - /
|
|
233
|
+
* - /static/...
|
|
234
|
+
* - /.well-known/...
|
|
235
|
+
* - /not-found
|
|
236
|
+
* - /app
|
|
237
|
+
* - /app/enter
|
|
238
|
+
* - /app/config
|
|
239
|
+
* - /logout
|
|
240
|
+
* - /login/:method
|
|
241
|
+
* <br/>
|
|
242
|
+
* NOTE: You can define custom unprotected routes by overriding the {@link TiWebServer#defineUnprotectedRoutes} method.
|
|
243
|
+
*
|
|
244
|
+
* @method
|
|
245
|
+
* @param {string} route
|
|
246
|
+
* @returns {boolean}
|
|
247
|
+
* @public
|
|
248
|
+
*/
|
|
249
|
+
isUnprotectedRoute(route: string): boolean;
|
|
250
|
+
/**
|
|
251
|
+
* Used to define the web application routes.
|
|
252
|
+
* <br/>
|
|
253
|
+
* NOTE: Override this to define custom web application routes. Remember to call the base method if you want to preserve the default behavior as well.
|
|
254
|
+
*
|
|
255
|
+
* @method
|
|
256
|
+
* @virtual
|
|
257
|
+
* @public
|
|
258
|
+
*/
|
|
259
|
+
defineWebApplicationRoutes(): void;
|
|
260
|
+
/**
|
|
261
|
+
* Used to define the unprotected routes (i.e., routes that do not require authentication).
|
|
262
|
+
* <br/>
|
|
263
|
+
* NOTE: Override this to define custom unprotected routes. Remember to call the base method if you want to preserve the default behavior as well.
|
|
264
|
+
*
|
|
265
|
+
* @method
|
|
266
|
+
* @virtual
|
|
267
|
+
* @public
|
|
268
|
+
*/
|
|
269
|
+
defineUnprotectedRoutes(): void;
|
|
270
|
+
/**
|
|
271
|
+
* Registers a custom application route on the underlying Express app.
|
|
272
|
+
* <br/>
|
|
273
|
+
* NOTE: Call this from a {@link TiWebServer#defineWebApplicationRoutes} override AFTER invoking the base method,
|
|
274
|
+
* so the framework's own routes keep priority and any catch-all route you add resolves last (it will still be
|
|
275
|
+
* registered before the framework's own `*splat` 404 handler). It is only valid once the Express app exists —
|
|
276
|
+
* i.e., from within {@link TiWebServer#defineWebApplicationRoutes}, which {@link TiWebServer#onStart} invokes.
|
|
277
|
+
*
|
|
278
|
+
* @method
|
|
279
|
+
* @param {string} method One of the supported routing verbs: get, post, put, patch, delete, options, head, all.
|
|
280
|
+
* @param {string|RegExp} path The route path or pattern.
|
|
281
|
+
* @param {...Function} handlers One or more Express route handlers/middleware.
|
|
282
|
+
* @returns {TiWebServer} This instance, to allow chaining.
|
|
283
|
+
* @public
|
|
284
|
+
*/
|
|
285
|
+
registerRoute(method: string, path: string | RegExp, ...handlers: Function[]): TiWebServer;
|
|
286
|
+
/**
|
|
287
|
+
* Adds a pattern to the unprotected-routes list — routes that bypass the authentication gate. A string is
|
|
288
|
+
* matched exactly against the request path; a RegExp is tested against it. Consulted at request time by
|
|
289
|
+
* {@link TiWebServer#isUnprotectedRoute}.
|
|
290
|
+
* <br/>
|
|
291
|
+
* NOTE: Call this from a {@link TiWebServer#defineUnprotectedRoutes} override AFTER invoking the base method, to
|
|
292
|
+
* extend (rather than replace) the defaults.
|
|
293
|
+
*
|
|
294
|
+
* @method
|
|
295
|
+
* @param {string|RegExp} pattern The exact path (string) or path matcher (RegExp) to treat as unprotected.
|
|
296
|
+
* @returns {TiWebServer} This instance, to allow chaining.
|
|
297
|
+
* @public
|
|
298
|
+
*/
|
|
299
|
+
addUnprotectedRoute(pattern: string | RegExp): TiWebServer;
|
|
300
|
+
/**
|
|
301
|
+
* Resolves a `staticCache` configuration block into the policy the `/static` mounts apply, filling in
|
|
302
|
+
* {@link TiWebServer.#STATIC_CACHE_DEFAULTS} per key and rejecting values that cannot be honored. Pure: problems
|
|
303
|
+
* are returned as `warnings` rather than logged, so the caller decides how to surface them and a test can assert
|
|
304
|
+
* on them. Static and exposed for unit testing — not part of the customization surface.
|
|
305
|
+
* <br/>
|
|
306
|
+
* `maxAge` is a whole number of SECONDS, mapping 1:1 onto the `Cache-Control` directive — express's `"1y"`-style
|
|
307
|
+
* duration strings are NOT accepted, and are reported rather than silently reinterpreted as milliseconds.
|
|
308
|
+
* <br/>
|
|
309
|
+
* `immutable` is dropped (with a warning) when `maxAge` is 0, because a response that is stale on arrival yet
|
|
310
|
+
* promises never to change is a contradiction. Dropping it fails safe: the misconfiguration costs a revalidation,
|
|
311
|
+
* not a year of unreachable assets.
|
|
312
|
+
*
|
|
313
|
+
* @method
|
|
314
|
+
* @static
|
|
315
|
+
* @param {SettingsStaticCache} [staticCache] The configured block, if any.
|
|
316
|
+
* @returns {{maxAge: number, immutable: boolean, immutablePaths: string[], warnings: string[]}}
|
|
317
|
+
* @public
|
|
318
|
+
*/
|
|
319
|
+
static resolveStaticCachePolicy(staticCache?: SettingsStaticCache): {
|
|
320
|
+
maxAge: number;
|
|
321
|
+
immutable: boolean;
|
|
322
|
+
immutablePaths: string[];
|
|
323
|
+
warnings: string[];
|
|
324
|
+
};
|
|
325
|
+
/**
|
|
326
|
+
* Builds the `Cache-Control` value for one static file: the long-lived immutable policy when its served path sits
|
|
327
|
+
* under a configured `immutablePaths` prefix (matched case-sensitively, so a case mismatch falls back to the safe
|
|
328
|
+
* side), otherwise the policy's own `maxAge`/`immutable`. A `maxAge` of 0 is emitted as an explicit
|
|
329
|
+
* `must-revalidate` rather than a bare `max-age=0`, matching what the sibling `web-content` package serves.
|
|
330
|
+
* Pure and static; exposed for unit testing — not part of the customization surface.
|
|
331
|
+
*
|
|
332
|
+
* @method
|
|
333
|
+
* @static
|
|
334
|
+
* @param {string} rootPath The directory this `/static` mount serves.
|
|
335
|
+
* @param {string} filePath The absolute path of the file being served.
|
|
336
|
+
* @param {Object} policy A policy as returned by {@link TiWebServer.resolveStaticCachePolicy}.
|
|
337
|
+
* @returns {string}
|
|
338
|
+
* @public
|
|
339
|
+
*/
|
|
340
|
+
static staticCacheControlFor(rootPath: string, filePath: string, policy: Object): string;
|
|
341
|
+
/**
|
|
342
|
+
* Normalizes an HTTP method to a lower-case Express routing verb, or returns null if it is not a supported,
|
|
343
|
+
* registrable verb. Anything that is not a string is rejected outright rather than coerced — otherwise a value
|
|
344
|
+
* whose `toString()` happens to yield a verb (`[ "get" ]`, `new String( "get" )`) would register a route and
|
|
345
|
+
* bypass the `E_GEN_INVALID_ARGUMENT_TYPE` that {@link TiWebServer#registerRoute} raises for a bad method.
|
|
346
|
+
* Pure and static; exposed for unit testing — not part of the customization surface.
|
|
347
|
+
*
|
|
348
|
+
* @method
|
|
349
|
+
* @static
|
|
350
|
+
* @param {string} method
|
|
351
|
+
* @returns {string|null}
|
|
352
|
+
* @public
|
|
353
|
+
*/
|
|
354
|
+
static normalizeRegistrableMethod(method: string): string | null;
|
|
355
|
+
/**
|
|
356
|
+
* Tests a request path against a list of unprotected-route patterns (string exact-match or RegExp test),
|
|
357
|
+
* returning true on the first match. A RegExp's `lastIndex` is reset defensively so a stateful 'g'/'y' flag
|
|
358
|
+
* cannot cause a match to be skipped. Pure and static; shared by {@link TiWebServer#isUnprotectedRoute} and
|
|
359
|
+
* exposed for unit testing — not part of the customization surface.
|
|
360
|
+
*
|
|
361
|
+
* @method
|
|
362
|
+
* @static
|
|
363
|
+
* @param {Array<string|RegExp>} patterns
|
|
364
|
+
* @param {string} pathOnly The request path with any query string already stripped.
|
|
365
|
+
* @returns {boolean}
|
|
366
|
+
* @public
|
|
367
|
+
*/
|
|
368
|
+
static isRouteInList(patterns: Array<string | RegExp>, pathOnly: string): boolean;
|
|
369
|
+
}
|
|
370
|
+
declare namespace TiWebServer {
|
|
371
|
+
export { RE_STATIC_UNPROTECTED };
|
|
372
|
+
export { RE_WELL_KNOWN_UNPROTECTED };
|
|
373
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare var listEditors: (service: ConfigService) => ExpressHandler;
|
|
2
|
+
export declare var composeView: (service: any) => (request: any, response: any, next: any) => void;
|
|
3
|
+
export declare var saveEditorEdit: (service: any) => (request: any, response: any, next: any) => void;
|
|
4
|
+
export declare var getCurrent: (service: any) => (request: any, response: any, next: any) => void;
|
|
5
|
+
export declare var getHistory: (service: any) => (request: any, response: any, next: any) => void;
|
|
6
|
+
export declare var listChanges: (service: any) => (request: any, response: any, next: any) => void;
|
|
7
|
+
export declare var getChange: (service: any) => (request: any, response: any, next: any) => void;
|
|
8
|
+
export declare var restoreChangeSet: (service: any) => (request: any, response: any, next: any) => void;
|
|
9
|
+
export declare var exportBundle: (service: any) => (request: any, response: any, next: any) => void;
|
|
10
|
+
import type ConfigService from "#config-service";
|
|
11
|
+
import type { ExpressHandler } from "#web-handlers";
|