@serve.zone/platformclient 2.2.0 → 2.3.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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.platformclient.d.ts +2 -0
- package/dist_ts/classes.platformclient.js +7 -2
- package/dist_ts/index.d.ts +1 -0
- package/dist_ts/index.js +2 -1
- package/dist_ts/webpush/classes.webpushconnector.d.ts +47 -0
- package/dist_ts/webpush/classes.webpushconnector.js +260 -0
- package/package.json +2 -2
- package/readme.md +56 -3
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.platformclient.ts +6 -1
- package/ts/index.ts +1 -0
- package/ts/webpush/classes.webpushconnector.ts +341 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@serve.zone/platformclient',
|
|
6
|
-
version: '2.
|
|
6
|
+
version: '2.3.0',
|
|
7
7
|
description: 'a module that makes it really easy to use the serve.zone platform inside your app'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSw0QkFBNEI7SUFDbEMsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLG1GQUFtRjtDQUNqRyxDQUFBIn0=
|
|
@@ -2,6 +2,7 @@ import { SzEmailConnector } from './email/classes.emailconnector.js';
|
|
|
2
2
|
import { SzSmsConnector } from './email/classes.smsconnector.js';
|
|
3
3
|
import { SzPushNotificationConnector } from './email/classes.pushnotificationconnector.js';
|
|
4
4
|
import { SzLetterConnector } from './email/classes.letterconnector.js';
|
|
5
|
+
import { SzWebPushConnector } from './webpush/classes.webpushconnector.js';
|
|
5
6
|
import * as plugins from './plugins.js';
|
|
6
7
|
export interface ISzPlatformClientOptions {
|
|
7
8
|
authorizationString?: string;
|
|
@@ -23,6 +24,7 @@ export declare class SzPlatformClient {
|
|
|
23
24
|
emailConnector: SzEmailConnector;
|
|
24
25
|
smsConnector: SzSmsConnector;
|
|
25
26
|
pushNotificationConnector: SzPushNotificationConnector;
|
|
27
|
+
webPushConnector: SzWebPushConnector;
|
|
26
28
|
letterConnector: SzLetterConnector;
|
|
27
29
|
constructor(authorizationStringArg?: string | ISzPlatformClientOptions);
|
|
28
30
|
init(authorizationStringArg?: string | ISzPlatformClientOptions): Promise<void>;
|
|
@@ -2,6 +2,7 @@ import { SzEmailConnector } from './email/classes.emailconnector.js';
|
|
|
2
2
|
import { SzSmsConnector } from './email/classes.smsconnector.js';
|
|
3
3
|
import { SzPushNotificationConnector } from './email/classes.pushnotificationconnector.js';
|
|
4
4
|
import { SzLetterConnector } from './email/classes.letterconnector.js';
|
|
5
|
+
import { SzWebPushConnector } from './webpush/classes.webpushconnector.js';
|
|
5
6
|
import * as plugins from './plugins.js';
|
|
6
7
|
export class SzPlatformClient {
|
|
7
8
|
constructor(authorizationStringArg) {
|
|
@@ -12,6 +13,7 @@ export class SzPlatformClient {
|
|
|
12
13
|
this.emailConnector = new SzEmailConnector(this);
|
|
13
14
|
this.smsConnector = new SzSmsConnector(this);
|
|
14
15
|
this.pushNotificationConnector = new SzPushNotificationConnector(this);
|
|
16
|
+
this.webPushConnector = new SzWebPushConnector(this);
|
|
15
17
|
this.letterConnector = new SzLetterConnector(this);
|
|
16
18
|
this.applyOptions(authorizationStringArg);
|
|
17
19
|
}
|
|
@@ -129,7 +131,10 @@ export class SzPlatformClient {
|
|
|
129
131
|
}
|
|
130
132
|
}
|
|
131
133
|
async stop() {
|
|
132
|
-
await
|
|
134
|
+
await Promise.all([
|
|
135
|
+
this.emailConnector.stop(),
|
|
136
|
+
this.webPushConnector.stop(),
|
|
137
|
+
]);
|
|
133
138
|
if (this.typedsocket) {
|
|
134
139
|
await this.typedsocket.stop();
|
|
135
140
|
}
|
|
@@ -181,4 +186,4 @@ export class SzPlatformClient {
|
|
|
181
186
|
return processEnv?.[envNameArg];
|
|
182
187
|
}
|
|
183
188
|
}
|
|
184
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
189
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wbGF0Zm9ybWNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMucGxhdGZvcm1jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDckUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLDhDQUE4QyxDQUFDO0FBQzNGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzNFLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBWXhDLE1BQU0sT0FBTyxnQkFBZ0I7SUFlM0IsWUFBWSxzQkFBMEQ7UUFkL0QsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUdsQixxQkFBZ0IsR0FBNEQsRUFBRSxDQUFDO1FBQy9FLGdCQUFXLEdBQXFDLElBQUksT0FBTyxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUV0RixpQkFBWSxHQUFHLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUV4QyxtQkFBYyxHQUFHLElBQUksZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDNUMsaUJBQVksR0FBRyxJQUFJLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4Qyw4QkFBeUIsR0FBRyxJQUFJLDJCQUEyQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xFLHFCQUFnQixHQUFHLElBQUksa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEQsb0JBQWUsR0FBRyxJQUFJLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBR25ELElBQUksQ0FBQyxZQUFZLENBQUMsc0JBQXNCLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRU0sS0FBSyxDQUFDLElBQUksQ0FBQyxzQkFBMEQ7UUFDMUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUM5QixJQUFJLENBQUMsbUJBQW1CLEdBQUcsTUFBTSxJQUFJLENBQUMsZ0NBQWdDLEVBQUUsQ0FBQztRQUMzRSxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDeEMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDekIsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUNoRCxJQUFJLENBQUMsZ0JBQWdCLEVBQ3JCLE1BQU0sSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQ3RDLENBQUM7UUFDRixJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDOUIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxrQ0FBa0MsRUFBRSxDQUFDO1FBQ3ZFLENBQUM7UUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQjtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsaUNBQWlDLENBQUMsQ0FBQztRQUNsRixJQUFJLElBQUksQ0FBQyxtQkFBbUIsS0FBSyxNQUFNLEVBQUUsQ0FBQztZQUN4QyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUN6QixPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxXQUFXLEdBQUcsTUFBTSxPQUFPLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQ25FLElBQUksQ0FBQyxXQUFrQixFQUN2QixNQUFNLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUNsQyxDQUFDO1FBQ0YsTUFBTSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztJQUNuQyxDQUFDO0lBRU8saUJBQWlCO1FBQ3ZCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLE9BQU8sQ0FBQyxHQUFHLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRU0sa0JBQWtCLENBQ3ZCLGFBQXdFO1FBRXhFLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLFVBQVUsRUFBRSxFQUFFO1lBQy9DLE9BQU8sQ0FDTCxVQUFVLENBQUMsWUFBWSxLQUFLLFVBQVU7Z0JBQ3RDLFVBQVUsQ0FBQyxNQUFNLEtBQUssUUFBUTtnQkFDOUIsQ0FBQyxDQUFDLGFBQWEsSUFBSSxVQUFVLENBQUMsVUFBVSxLQUFLLGFBQWEsQ0FBQyxDQUM1RCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sWUFBWSxDQUFDLFVBQThDO1FBQ2pFLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNoQixPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksT0FBTyxVQUFVLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDbkMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLFVBQVUsQ0FBQztZQUN0QyxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksQ0FBQyxtQkFBbUI7WUFDdEIsVUFBVSxDQUFDLG1CQUFtQjtnQkFDOUIsVUFBVSxDQUFDLGFBQWE7Z0JBQ3hCLFVBQVUsQ0FBQyxLQUFLO2dCQUNoQixJQUFJLENBQUMsbUJBQW1CLENBQUM7UUFDM0IsSUFBSSxDQUFDLGlCQUFpQixHQUFHLFVBQVUsQ0FBQyxHQUFHLElBQUksVUFBVSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUM7UUFDNUYsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FDaEQsSUFBSSxDQUFDLGdCQUFnQixFQUNyQixDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLFVBQVUsQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQ3pELE9BQU8sQ0FDbUQsQ0FDN0QsQ0FBQztJQUNKLENBQUM7SUFFTyxLQUFLLENBQUMsb0JBQW9CO1FBQ2hDLE1BQU0saUJBQWlCLEdBQ3JCLElBQUksQ0FBQyxpQkFBaUI7WUFDdEIsQ0FBQyxNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1lBQzFELElBQUksQ0FBQyxnQ0FBZ0MsRUFBRSxDQUFDO1FBQzFDLElBQUksQ0FBQyxpQkFBaUI7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLGlFQUFpRSxDQUFDLENBQUM7UUFDM0csT0FBTyxpQkFBaUIsQ0FBQztJQUMzQixDQUFDO0lBRU8sZ0NBQWdDO1FBQ3RDLEtBQUssTUFBTSxPQUFPLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDNUMsSUFBSSxPQUFPLENBQUMsWUFBWSxLQUFLLFVBQVUsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLFFBQVEsRUFBRSxDQUFDO2dCQUN2RSxTQUFTO1lBQ1gsQ0FBQztZQUNELElBQUksQ0FBQyxJQUFJLENBQUMsOEJBQThCLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7Z0JBQzdELFNBQVM7WUFDWCxDQUFDO1lBQ0QsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRTtnQkFDdkQsT0FBTyxXQUFXLENBQUMsUUFBUSxLQUFLLGNBQWMsSUFBSSxXQUFXLENBQUMsUUFBUSxLQUFLLE1BQU0sQ0FBQztZQUNwRixDQUFDLENBQUMsQ0FBQztZQUNILE1BQU0sV0FBVyxHQUFHLFFBQVEsRUFBRSxXQUFXLElBQUksUUFBUSxFQUFFLFdBQVcsQ0FBQztZQUNuRSxJQUFJLFdBQVcsRUFBRSxDQUFDO2dCQUNoQixPQUFPLFdBQVcsQ0FBQztZQUNyQixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFTyw4QkFBOEIsQ0FDcEMsYUFBdUU7UUFFdkUsT0FBTyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2hGLENBQUM7SUFFTyxLQUFLLENBQUMsZ0NBQWdDO1FBQzVDLE9BQU8sQ0FDTCxDQUFDLE1BQU0sSUFBSSxDQUFDLG1CQUFtQixDQUFDLGtDQUFrQyxDQUFDLENBQUM7WUFDcEUsQ0FBQyxNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDLENBQzdELENBQUM7SUFDSixDQUFDO0lBRU8sa0NBQWtDO1FBQ3hDLE1BQU0sWUFBWSxHQUFHO1lBQ25CLGtDQUFrQztZQUNsQywwQkFBMEI7WUFDMUIscUJBQXFCO1lBQ3JCLGVBQWU7WUFDZixPQUFPO1NBQ1IsQ0FBQztRQUNGLEtBQUssTUFBTSxPQUFPLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDNUMsS0FBSyxNQUFNLFVBQVUsSUFBSSxPQUFPLENBQUMsV0FBVyxJQUFJLEVBQUUsRUFBRSxDQUFDO2dCQUNuRCxLQUFLLE1BQU0sT0FBTyxJQUFJLFlBQVksRUFBRSxDQUFDO29CQUNuQyxNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ3hDLElBQUksS0FBSyxFQUFFLENBQUM7d0JBQ1YsT0FBTyxLQUFLLENBQUM7b0JBQ2YsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLG1CQUFtQjtRQUMvQixJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDOUIsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLGVBQXNCLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDbEYsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixJQUFJLE1BQU0sSUFBSSxDQUFDLG1CQUFtQixDQUFDLGdDQUFnQyxDQUFDLEVBQUUsQ0FBQztnQkFDckUsT0FBTyxDQUFDLElBQUksQ0FBQywyQ0FBMkMsRUFBRyxLQUFlLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDdEYsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRU0sS0FBSyxDQUFDLElBQUk7UUFDZixNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUM7WUFDaEIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUU7WUFDMUIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRTtTQUM3QixDQUFDLENBQUM7UUFDSCxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyQixNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDaEMsQ0FBQztJQUNILENBQUM7SUFFTyxLQUFLLENBQUMsd0JBQXdCO1FBQ3BDLE1BQU0sUUFBUSxHQUE0RCxFQUFFLENBQUM7UUFDN0UsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQUMsNkJBQTZCLENBQUMsQ0FBQztRQUNsRixNQUFNLFVBQVUsR0FBRyxNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO1FBRWhGLElBQUksV0FBVyxFQUFFLENBQUM7WUFDaEIsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyw2QkFBNkIsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDO1FBQzlGLENBQUM7UUFDRCxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2YsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyw0QkFBNEIsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQzVGLENBQUM7UUFFRCxPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBRU8sd0JBQXdCLENBQUMsVUFBa0IsRUFBRSxXQUFtQjtRQUN0RSxJQUFJLFdBQW9CLENBQUM7UUFDekIsSUFBSSxDQUFDO1lBQ0gsV0FBVyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDeEMsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsVUFBVSwwQkFBMEIsQ0FBQyxDQUFDO1FBQzNELENBQUM7UUFFRCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztZQUMvQixPQUFPLFdBQXNFLENBQUM7UUFDaEYsQ0FBQztRQUNELElBQUksV0FBVyxJQUFJLE9BQU8sV0FBVyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ25ELE9BQU8sQ0FBQyxXQUFvRSxDQUFDLENBQUM7UUFDaEYsQ0FBQztRQUNELE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxVQUFVLGtEQUFrRCxDQUFDLENBQUM7SUFDbkYsQ0FBQztJQUVPLHFCQUFxQixDQUMzQixtQkFBNEUsRUFDNUUsY0FBdUU7UUFFdkUsTUFBTSxVQUFVLEdBQUcsSUFBSSxHQUFHLEVBQWlFLENBQUM7UUFDNUYsS0FBSyxNQUFNLE9BQU8sSUFBSSxDQUFDLEdBQUcsbUJBQW1CLEVBQUUsR0FBRyxjQUFjLENBQUMsRUFBRSxDQUFDO1lBQ2xFLFVBQVUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN0QyxDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFTSxLQUFLLENBQUMsbUJBQW1CLENBQUMsVUFBa0I7UUFDakQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3ZELElBQUksWUFBWSxFQUFFLENBQUM7WUFDakIsT0FBTyxZQUFZLENBQUM7UUFDdEIsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBRU8sZ0JBQWdCLENBQUMsVUFBa0I7UUFDekMsTUFBTSxVQUFVLEdBQUksVUFFbEIsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDO1FBQ2hCLE9BQU8sVUFBVSxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDbEMsQ0FBQztDQUNGIn0=
|
package/dist_ts/index.d.ts
CHANGED
package/dist_ts/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export * from './classes.platformclient.js';
|
|
2
2
|
export * from './email/classes.emailconnector.js';
|
|
3
|
-
|
|
3
|
+
export * from './webpush/classes.webpushconnector.js';
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLDZCQUE2QixDQUFDO0FBQzVDLGNBQWMsbUNBQW1DLENBQUM7QUFDbEQsY0FBYyx1Q0FBdUMsQ0FBQyJ9
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { SzPlatformClient } from '../classes.platformclient.js';
|
|
2
|
+
import * as plugins from '../plugins.js';
|
|
3
|
+
export interface IServiceWebPushCredentials {
|
|
4
|
+
typedUrl: string;
|
|
5
|
+
credentialId: string;
|
|
6
|
+
credentialSecret: string;
|
|
7
|
+
}
|
|
8
|
+
export interface IServiceWebPushConfigurationStatus {
|
|
9
|
+
configured: boolean;
|
|
10
|
+
typedUrl?: string;
|
|
11
|
+
credentialIdConfigured: boolean;
|
|
12
|
+
credentialSecretConfigured: boolean;
|
|
13
|
+
missing: string[];
|
|
14
|
+
}
|
|
15
|
+
export interface IServiceWebPushEnqueueOptions extends Omit<plugins.servezoneInterfaces.requests.webpush.IReq_EnqueueWebPush['request'], 'auth' | 'owner'> {
|
|
16
|
+
}
|
|
17
|
+
export type TServiceWebPushCancellationTarget = plugins.servezoneInterfaces.data.TWebPushCancellationTarget;
|
|
18
|
+
/**
|
|
19
|
+
* Credential-scoped Web Push delivery for a deployed service.
|
|
20
|
+
*
|
|
21
|
+
* This connector is separate from the legacy device-token push connector. It
|
|
22
|
+
* only accepts the service credential injected into the workload and never
|
|
23
|
+
* sends a caller-provided owner scope.
|
|
24
|
+
*/
|
|
25
|
+
export declare class SzWebPushConnector {
|
|
26
|
+
platformClientRef: SzPlatformClient;
|
|
27
|
+
private webPushTypedSocket?;
|
|
28
|
+
private webPushTypedSocketUrl?;
|
|
29
|
+
private webPushTypedSocketPromise?;
|
|
30
|
+
private webPushTypedSocketAbortController?;
|
|
31
|
+
constructor(platformClientRefArg: SzPlatformClient);
|
|
32
|
+
getConfigurationStatus(): Promise<IServiceWebPushConfigurationStatus>;
|
|
33
|
+
getWebPushServiceStatus(): Promise<plugins.servezoneInterfaces.data.IWebPushServiceStatus>;
|
|
34
|
+
getWebPushPublicKey(): Promise<string>;
|
|
35
|
+
enqueueWebPush(optionsArg: IServiceWebPushEnqueueOptions): Promise<plugins.servezoneInterfaces.requests.webpush.IReq_EnqueueWebPush['response']>;
|
|
36
|
+
cancelWebPush(targetArg: TServiceWebPushCancellationTarget): Promise<plugins.servezoneInterfaces.requests.webpush.IReq_CancelWebPush['response']>;
|
|
37
|
+
getWebPushDeliveryStatus(spoolItemIdArg: string): Promise<plugins.servezoneInterfaces.data.IWebPushDeliveryStatus | undefined>;
|
|
38
|
+
stop(): Promise<void>;
|
|
39
|
+
private getAuthenticatedClient;
|
|
40
|
+
private getCredentials;
|
|
41
|
+
private readWebPushEnv;
|
|
42
|
+
private normalizeCredentialBundle;
|
|
43
|
+
private hasCredentialBundleValue;
|
|
44
|
+
private normalizeConfigValue;
|
|
45
|
+
private getWebPushTypedSocket;
|
|
46
|
+
private normalizeTypedSocketUrl;
|
|
47
|
+
}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
/**
|
|
3
|
+
* Credential-scoped Web Push delivery for a deployed service.
|
|
4
|
+
*
|
|
5
|
+
* This connector is separate from the legacy device-token push connector. It
|
|
6
|
+
* only accepts the service credential injected into the workload and never
|
|
7
|
+
* sends a caller-provided owner scope.
|
|
8
|
+
*/
|
|
9
|
+
export class SzWebPushConnector {
|
|
10
|
+
constructor(platformClientRefArg) {
|
|
11
|
+
this.platformClientRef = platformClientRefArg;
|
|
12
|
+
}
|
|
13
|
+
async getConfigurationStatus() {
|
|
14
|
+
const env = await this.readWebPushEnv();
|
|
15
|
+
const missing = [];
|
|
16
|
+
if (!env.typedUrl)
|
|
17
|
+
missing.push('WEB_PUSH_TYPED_URL');
|
|
18
|
+
if (!env.credentialId)
|
|
19
|
+
missing.push('WEB_PUSH_API_CREDENTIAL_ID');
|
|
20
|
+
if (!env.credentialSecret)
|
|
21
|
+
missing.push('WEB_PUSH_API_CREDENTIAL_SECRET');
|
|
22
|
+
return {
|
|
23
|
+
configured: missing.length === 0,
|
|
24
|
+
typedUrl: env.typedUrl ? this.normalizeTypedSocketUrl(env.typedUrl) : undefined,
|
|
25
|
+
credentialIdConfigured: Boolean(env.credentialId),
|
|
26
|
+
credentialSecretConfigured: Boolean(env.credentialSecret),
|
|
27
|
+
missing,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
async getWebPushServiceStatus() {
|
|
31
|
+
if (this.platformClientRef.debugMode) {
|
|
32
|
+
return {
|
|
33
|
+
ready: false,
|
|
34
|
+
bindingId: 'debug',
|
|
35
|
+
bindingStatus: 'disabled',
|
|
36
|
+
retiringVapidKeys: [],
|
|
37
|
+
maxPayloadBytes: 0,
|
|
38
|
+
maxTtlSeconds: 0,
|
|
39
|
+
contentEncoding: 'aes128gcm',
|
|
40
|
+
message: 'Web Push is disabled in platformclient debug mode',
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const { typedSocket, auth } = await this.getAuthenticatedClient();
|
|
44
|
+
const request = typedSocket.createTypedRequest('getWebPushServiceStatus');
|
|
45
|
+
return await request.fire({ auth });
|
|
46
|
+
}
|
|
47
|
+
async getWebPushPublicKey() {
|
|
48
|
+
const status = await this.getWebPushServiceStatus();
|
|
49
|
+
if (!status.ready || !status.activeVapidKey?.publicKey) {
|
|
50
|
+
throw new Error(status.message || 'Web Push is not ready');
|
|
51
|
+
}
|
|
52
|
+
return status.activeVapidKey.publicKey;
|
|
53
|
+
}
|
|
54
|
+
async enqueueWebPush(optionsArg) {
|
|
55
|
+
if (!optionsArg.idempotencyKey?.trim()) {
|
|
56
|
+
throw new Error('idempotencyKey is required');
|
|
57
|
+
}
|
|
58
|
+
if (!optionsArg.subscriptionId?.trim()) {
|
|
59
|
+
throw new Error('subscriptionId is required');
|
|
60
|
+
}
|
|
61
|
+
if (this.platformClientRef.debugMode) {
|
|
62
|
+
return {
|
|
63
|
+
accepted: true,
|
|
64
|
+
spoolItemId: 'debug',
|
|
65
|
+
message: 'Web Push accepted in platformclient debug mode',
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const { typedSocket, auth } = await this.getAuthenticatedClient();
|
|
69
|
+
const request = typedSocket.createTypedRequest('enqueueWebPush');
|
|
70
|
+
return await request.fire({
|
|
71
|
+
auth,
|
|
72
|
+
idempotencyKey: optionsArg.idempotencyKey.trim(),
|
|
73
|
+
subscriptionId: optionsArg.subscriptionId.trim(),
|
|
74
|
+
subscription: optionsArg.subscription,
|
|
75
|
+
vapidKeyId: optionsArg.vapidKeyId,
|
|
76
|
+
payload: optionsArg.payload,
|
|
77
|
+
ttlSeconds: optionsArg.ttlSeconds,
|
|
78
|
+
urgency: optionsArg.urgency,
|
|
79
|
+
collapseKey: optionsArg.collapseKey,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
async cancelWebPush(targetArg) {
|
|
83
|
+
if (targetArg.type === 'spoolItem' && !targetArg.spoolItemId?.trim()) {
|
|
84
|
+
throw new Error('spoolItemId is required');
|
|
85
|
+
}
|
|
86
|
+
if (targetArg.type === 'subscription' && !targetArg.subscriptionId?.trim()) {
|
|
87
|
+
throw new Error('subscriptionId is required');
|
|
88
|
+
}
|
|
89
|
+
const target = targetArg.type === 'spoolItem'
|
|
90
|
+
? { type: 'spoolItem', spoolItemId: targetArg.spoolItemId.trim() }
|
|
91
|
+
: { type: 'subscription', subscriptionId: targetArg.subscriptionId.trim() };
|
|
92
|
+
if (this.platformClientRef.debugMode) {
|
|
93
|
+
return {
|
|
94
|
+
success: true,
|
|
95
|
+
cancelledCount: 0,
|
|
96
|
+
alreadyTerminalCount: 0,
|
|
97
|
+
message: 'Web Push cancellation accepted in platformclient debug mode',
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
const { typedSocket, auth } = await this.getAuthenticatedClient();
|
|
101
|
+
const request = typedSocket.createTypedRequest('cancelWebPush');
|
|
102
|
+
return await request.fire({ auth, target });
|
|
103
|
+
}
|
|
104
|
+
async getWebPushDeliveryStatus(spoolItemIdArg) {
|
|
105
|
+
const spoolItemId = String(spoolItemIdArg || '').trim();
|
|
106
|
+
if (!spoolItemId) {
|
|
107
|
+
throw new Error('spoolItemId is required');
|
|
108
|
+
}
|
|
109
|
+
if (this.platformClientRef.debugMode) {
|
|
110
|
+
return {
|
|
111
|
+
spoolItemId,
|
|
112
|
+
state: 'queued',
|
|
113
|
+
attempts: 0,
|
|
114
|
+
acceptedAt: 0,
|
|
115
|
+
updatedAt: 0,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
const { typedSocket, auth } = await this.getAuthenticatedClient();
|
|
119
|
+
const request = typedSocket.createTypedRequest('getWebPushDeliveryStatus');
|
|
120
|
+
const result = await request.fire({ auth, spoolItemId });
|
|
121
|
+
return result.delivery;
|
|
122
|
+
}
|
|
123
|
+
async stop() {
|
|
124
|
+
const socket = this.webPushTypedSocket;
|
|
125
|
+
const socketPromise = this.webPushTypedSocketPromise;
|
|
126
|
+
this.webPushTypedSocket = undefined;
|
|
127
|
+
this.webPushTypedSocketPromise = undefined;
|
|
128
|
+
this.webPushTypedSocketUrl = undefined;
|
|
129
|
+
this.webPushTypedSocketAbortController?.abort();
|
|
130
|
+
this.webPushTypedSocketAbortController = undefined;
|
|
131
|
+
if (socket) {
|
|
132
|
+
await socket.stop();
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (socketPromise) {
|
|
136
|
+
try {
|
|
137
|
+
const pendingSocket = await socketPromise;
|
|
138
|
+
await pendingSocket.stop();
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// A failed or aborted connection leaves no socket to close.
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
async getAuthenticatedClient() {
|
|
146
|
+
const credentials = await this.getCredentials();
|
|
147
|
+
return {
|
|
148
|
+
typedSocket: await this.getWebPushTypedSocket(credentials.typedUrl),
|
|
149
|
+
auth: {
|
|
150
|
+
credentialId: credentials.credentialId,
|
|
151
|
+
credentialSecret: credentials.credentialSecret,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
async getCredentials() {
|
|
156
|
+
const env = await this.readWebPushEnv();
|
|
157
|
+
if (!env.typedUrl)
|
|
158
|
+
throw new Error('WEB_PUSH_TYPED_URL is required for Web Push');
|
|
159
|
+
if (!env.credentialId) {
|
|
160
|
+
throw new Error('WEB_PUSH_API_CREDENTIAL_ID is required for Web Push');
|
|
161
|
+
}
|
|
162
|
+
if (!env.credentialSecret) {
|
|
163
|
+
throw new Error('WEB_PUSH_API_CREDENTIAL_SECRET is required for Web Push');
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
typedUrl: env.typedUrl,
|
|
167
|
+
credentialId: env.credentialId,
|
|
168
|
+
credentialSecret: env.credentialSecret,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
async readWebPushEnv() {
|
|
172
|
+
const directEnv = this.normalizeCredentialBundle({
|
|
173
|
+
typedUrl: await this.platformClientRef.getConfiguredEnvVar('WEB_PUSH_TYPED_URL'),
|
|
174
|
+
credentialId: await this.platformClientRef.getConfiguredEnvVar('WEB_PUSH_API_CREDENTIAL_ID'),
|
|
175
|
+
credentialSecret: await this.platformClientRef.getConfiguredEnvVar('WEB_PUSH_API_CREDENTIAL_SECRET'),
|
|
176
|
+
});
|
|
177
|
+
if (this.hasCredentialBundleValue(directEnv)) {
|
|
178
|
+
return directEnv;
|
|
179
|
+
}
|
|
180
|
+
const bindingCredentialBundles = [];
|
|
181
|
+
for (const binding of this.platformClientRef.platformBindings || []) {
|
|
182
|
+
if (binding.capability !== 'pushnotification'
|
|
183
|
+
|| binding.desiredState !== 'enabled'
|
|
184
|
+
|| binding.status !== 'ready') {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
for (const credential of binding.credentials || []) {
|
|
188
|
+
const credentialBundle = this.normalizeCredentialBundle({
|
|
189
|
+
typedUrl: credential.env?.WEB_PUSH_TYPED_URL,
|
|
190
|
+
credentialId: credential.env?.WEB_PUSH_API_CREDENTIAL_ID,
|
|
191
|
+
credentialSecret: credential.env?.WEB_PUSH_API_CREDENTIAL_SECRET,
|
|
192
|
+
});
|
|
193
|
+
if (this.hasCredentialBundleValue(credentialBundle)) {
|
|
194
|
+
bindingCredentialBundles.push(credentialBundle);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (bindingCredentialBundles.length > 1) {
|
|
199
|
+
throw new Error('Multiple ready Web Push credential bundles are configured; exactly one is required');
|
|
200
|
+
}
|
|
201
|
+
return bindingCredentialBundles[0] || {};
|
|
202
|
+
}
|
|
203
|
+
normalizeCredentialBundle(bundleArg) {
|
|
204
|
+
const typedUrl = this.normalizeConfigValue(bundleArg.typedUrl);
|
|
205
|
+
return {
|
|
206
|
+
typedUrl: typedUrl ? this.normalizeTypedSocketUrl(typedUrl) || undefined : undefined,
|
|
207
|
+
credentialId: this.normalizeConfigValue(bundleArg.credentialId),
|
|
208
|
+
credentialSecret: this.normalizeConfigValue(bundleArg.credentialSecret),
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
hasCredentialBundleValue(bundleArg) {
|
|
212
|
+
return Boolean(bundleArg.typedUrl
|
|
213
|
+
|| bundleArg.credentialId
|
|
214
|
+
|| bundleArg.credentialSecret);
|
|
215
|
+
}
|
|
216
|
+
normalizeConfigValue(valueArg) {
|
|
217
|
+
const value = valueArg?.trim();
|
|
218
|
+
return value || undefined;
|
|
219
|
+
}
|
|
220
|
+
async getWebPushTypedSocket(urlArg) {
|
|
221
|
+
const normalizedUrl = this.normalizeTypedSocketUrl(urlArg);
|
|
222
|
+
if (this.webPushTypedSocket && this.webPushTypedSocketUrl === normalizedUrl) {
|
|
223
|
+
return this.webPushTypedSocket;
|
|
224
|
+
}
|
|
225
|
+
if (this.webPushTypedSocketPromise && this.webPushTypedSocketUrl === normalizedUrl) {
|
|
226
|
+
return await this.webPushTypedSocketPromise;
|
|
227
|
+
}
|
|
228
|
+
if (this.webPushTypedSocket || this.webPushTypedSocketPromise) {
|
|
229
|
+
await this.stop();
|
|
230
|
+
}
|
|
231
|
+
this.webPushTypedSocketUrl = normalizedUrl;
|
|
232
|
+
const abortController = new AbortController();
|
|
233
|
+
this.webPushTypedSocketAbortController = abortController;
|
|
234
|
+
const socketPromise = plugins.typedsocket.TypedSocket.createClient(this.platformClientRef.typedrouter, normalizedUrl, { autoReconnect: true, abortSignal: abortController.signal });
|
|
235
|
+
this.webPushTypedSocketPromise = socketPromise;
|
|
236
|
+
try {
|
|
237
|
+
const socket = await socketPromise;
|
|
238
|
+
if (this.webPushTypedSocketPromise === socketPromise
|
|
239
|
+
&& this.webPushTypedSocketUrl === normalizedUrl) {
|
|
240
|
+
this.webPushTypedSocket = socket;
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
await socket.stop();
|
|
244
|
+
}
|
|
245
|
+
return socket;
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
if (this.webPushTypedSocketPromise === socketPromise) {
|
|
249
|
+
this.webPushTypedSocketPromise = undefined;
|
|
250
|
+
this.webPushTypedSocketUrl = undefined;
|
|
251
|
+
this.webPushTypedSocketAbortController = undefined;
|
|
252
|
+
}
|
|
253
|
+
throw error;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
normalizeTypedSocketUrl(urlArg) {
|
|
257
|
+
return urlArg.trim().replace(/\/typedrequest\/?$/, '').replace(/\/+$/, '');
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy53ZWJwdXNoY29ubmVjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvd2VicHVzaC9jbGFzc2VzLndlYnB1c2hjb25uZWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUF3QnpDOzs7Ozs7R0FNRztBQUNILE1BQU0sT0FBTyxrQkFBa0I7SUFPN0IsWUFBWSxvQkFBc0M7UUFDaEQsSUFBSSxDQUFDLGlCQUFpQixHQUFHLG9CQUFvQixDQUFDO0lBQ2hELENBQUM7SUFFTSxLQUFLLENBQUMsc0JBQXNCO1FBQ2pDLE1BQU0sR0FBRyxHQUFHLE1BQU0sSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3hDLE1BQU0sT0FBTyxHQUFhLEVBQUUsQ0FBQztRQUM3QixJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVE7WUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDdEQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZO1lBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO1FBQ2xFLElBQUksQ0FBQyxHQUFHLENBQUMsZ0JBQWdCO1lBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO1FBQzFFLE9BQU87WUFDTCxVQUFVLEVBQUUsT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDO1lBQ2hDLFFBQVEsRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTO1lBQy9FLHNCQUFzQixFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDO1lBQ2pELDBCQUEwQixFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUM7WUFDekQsT0FBTztTQUNSLENBQUM7SUFDSixD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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serve.zone/platformclient",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "a module that makes it really easy to use the serve.zone platform inside your app",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@push.rocks/qenv": "^6.1.4",
|
|
23
23
|
"@push.rocks/smartlog": "^3.2.2",
|
|
24
24
|
"@push.rocks/smartntml": "^2.0.9",
|
|
25
|
-
"@serve.zone/interfaces": "^
|
|
25
|
+
"@serve.zone/interfaces": "^17.4.0"
|
|
26
26
|
},
|
|
27
27
|
"repository": {
|
|
28
28
|
"type": "git",
|
package/readme.md
CHANGED
|
@@ -41,6 +41,7 @@ await platformClient.emailConnector.sendEmail({
|
|
|
41
41
|
| `emailConnector` | `getServiceMailStatus()`, `getServiceMailCredentials()`, `sendMail()`, `sendText()`, `sendHtml()`, `getMailDeliveryStatus()`, `registerInboundHandler()`, `normalizeInboundMessage()`, `handleInboundPayload()`, `createInboundHandler()`, `sendEmail()` | `email` |
|
|
42
42
|
| `smsConnector` | `sendSms()`, `sendSmsVerifcation()` | `sms` |
|
|
43
43
|
| `pushNotificationConnector` | `sendPushNotification()` | `pushnotification` |
|
|
44
|
+
| `webPushConnector` | `getConfigurationStatus()`, `getWebPushServiceStatus()`, `getWebPushPublicKey()`, `enqueueWebPush()`, `cancelWebPush()`, `getWebPushDeliveryStatus()` | `pushnotification` |
|
|
44
45
|
| `letterConnector` | `sendLetter()` | `letter` |
|
|
45
46
|
|
|
46
47
|
The request and response payloads come from `@serve.zone/interfaces`, so TypeScript stays aligned with the serve.zone platform contracts.
|
|
@@ -59,6 +60,8 @@ Binding environment variables must contain JSON encoded `IPlatformBinding` objec
|
|
|
59
60
|
|
|
60
61
|
Service mail credentials can be provided directly as environment variables or through `email` platform binding credentials. Standard platformclient mail uses dcrouter TypedSocket/TypedRequest service credentials. The default sender uses `MAIL_FROM`, `MAIL_TYPED_URL`, `MAIL_API_CREDENTIAL_ID`, and `MAIL_API_CREDENTIAL_SECRET`. Additional configured sender addresses use scoped variables such as `MAIL_TEST_SERVICE_GATED_ONE_FROM`, `MAIL_TEST_SERVICE_GATED_ONE_TYPED_URL`, `MAIL_TEST_SERVICE_GATED_ONE_API_CREDENTIAL_ID`, and `MAIL_TEST_SERVICE_GATED_ONE_API_CREDENTIAL_SECRET`.
|
|
61
62
|
|
|
63
|
+
Managed Web Push uses a separate, credential-scoped TypedSocket connection configured with `WEB_PUSH_TYPED_URL`, `WEB_PUSH_API_CREDENTIAL_ID`, and `WEB_PUSH_API_CREDENTIAL_SECRET`. These values form one atomic bundle: if any direct variable is present, all three direct variables are required; otherwise exactly one credential object from a ready `pushnotification` binding must provide the bundle. Partial or ambiguous bundles fail closed and are never combined. `webPushConnector` never accepts or sends caller-provided authentication or resource-owner fields; dcrouter derives the service scope from the injected credential.
|
|
64
|
+
|
|
62
65
|
SMTP compatibility credentials are still discoverable with `getServiceMailCredentials()` for applications that explicitly implement SMTP themselves. Those compatibility variables are `SMTP_HOST`, `SMTP_PORT`, `SMTP_TLS_MODE`, `SMTP_USERNAME`, and `SMTP_PASSWORD`, plus scoped `MAIL_<TOKEN>_SMTP_*` variants. They are not used by `sendMail()`, `sendText()`, `sendHtml()`, or `registerInboundHandler()`.
|
|
63
66
|
|
|
64
67
|
```typescript
|
|
@@ -106,7 +109,7 @@ The current SMS verification method is spelled `sendSmsVerifcation()` in code. U
|
|
|
106
109
|
|
|
107
110
|
## Lifecycle
|
|
108
111
|
|
|
109
|
-
`SzPlatformClient` keeps TypedSocket connections open for platform requests
|
|
112
|
+
`SzPlatformClient` keeps TypedSocket connections open for platform requests, typed service-mail delivery, and managed Web Push delivery. Call `stop()` when a short-lived process, worker, or test is done with the client.
|
|
110
113
|
|
|
111
114
|
```typescript
|
|
112
115
|
const client = new SzPlatformClient({
|
|
@@ -202,7 +205,57 @@ const status = await client.smsConnector.sendSms({
|
|
|
202
205
|
});
|
|
203
206
|
```
|
|
204
207
|
|
|
205
|
-
Push
|
|
208
|
+
Managed Web Push:
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
const serviceStatus = await client.webPushConnector.getWebPushServiceStatus();
|
|
212
|
+
if (!serviceStatus.ready || !serviceStatus.activeVapidKey) {
|
|
213
|
+
throw new Error(serviceStatus.message || 'Web Push is not ready');
|
|
214
|
+
}
|
|
215
|
+
const activeVapidKey = serviceStatus.activeVapidKey;
|
|
216
|
+
const applicationServerKey = activeVapidKey.publicKey;
|
|
217
|
+
|
|
218
|
+
const browserSubscription = await serviceWorkerRegistration.pushManager.subscribe({
|
|
219
|
+
userVisibleOnly: true,
|
|
220
|
+
applicationServerKey,
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
const enqueueResult = await client.webPushConnector.enqueueWebPush({
|
|
224
|
+
idempotencyKey: 'notification-delivery-42',
|
|
225
|
+
subscriptionId: 'opaque-application-subscription-id',
|
|
226
|
+
subscription: browserSubscription.toJSON(),
|
|
227
|
+
vapidKeyId: activeVapidKey.id,
|
|
228
|
+
payload: {
|
|
229
|
+
schemaVersion: 1,
|
|
230
|
+
event: 'notificationAvailable',
|
|
231
|
+
eventId: 'notification-event-42',
|
|
232
|
+
route: '/notifications',
|
|
233
|
+
},
|
|
234
|
+
ttlSeconds: 300,
|
|
235
|
+
urgency: 'normal',
|
|
236
|
+
collapseKey: 'notification-inbox',
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
if (enqueueResult.spoolItemId) {
|
|
240
|
+
const delivery = await client.webPushConnector.getWebPushDeliveryStatus(
|
|
241
|
+
enqueueResult.spoolItemId,
|
|
242
|
+
);
|
|
243
|
+
console.log(delivery?.state);
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
The active VAPID key ID and public key come from one service-status snapshot, so a rotation cannot mismatch the subscription key and enqueue key ID. Store browser subscriptions as sensitive application data and only send the privacy-minimal `notificationAvailable` payload shown above. `enqueueWebPush().accepted` means dcrouter accepted the item into its delivery spool; it does not prove browser receipt or display. A terminal `pushServiceAccepted` state means the remote push service accepted the encrypted request.
|
|
248
|
+
|
|
249
|
+
Pending delivery can be cancelled by spool item or by opaque application subscription ID:
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
await client.webPushConnector.cancelWebPush({
|
|
253
|
+
type: 'subscription',
|
|
254
|
+
subscriptionId: 'opaque-application-subscription-id',
|
|
255
|
+
});
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Legacy device-token push:
|
|
206
259
|
|
|
207
260
|
```typescript
|
|
208
261
|
const status = await client.pushNotificationConnector.sendPushNotification({
|
|
@@ -223,7 +276,7 @@ await client.letterConnector.sendLetter({
|
|
|
223
276
|
});
|
|
224
277
|
```
|
|
225
278
|
|
|
226
|
-
Service-mail
|
|
279
|
+
Service-mail and managed Web Push helper types are exported from `@serve.zone/platformclient`. `IServiceMailSendResult.spoolItemId` identifies the dcrouter delivery spool item for follow-up status queries through `getMailDeliveryStatus(spoolItemId, address?)`. `IServiceWebPushEnqueueOptions` and `TServiceWebPushCancellationTarget` mirror the credential-scoped Web Push delivery contract without exposing auth or owner fields. The legacy platform-service request fields remain under `platform.email`, `platform.sms`, `platform.pushnotification`, and `platform.letter`.
|
|
227
280
|
|
|
228
281
|
## Platform Bindings
|
|
229
282
|
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { SzEmailConnector } from './email/classes.emailconnector.js';
|
|
|
2
2
|
import { SzSmsConnector } from './email/classes.smsconnector.js';
|
|
3
3
|
import { SzPushNotificationConnector } from './email/classes.pushnotificationconnector.js';
|
|
4
4
|
import { SzLetterConnector } from './email/classes.letterconnector.js';
|
|
5
|
+
import { SzWebPushConnector } from './webpush/classes.webpushconnector.js';
|
|
5
6
|
import * as plugins from './plugins.js';
|
|
6
7
|
|
|
7
8
|
export interface ISzPlatformClientOptions {
|
|
@@ -26,6 +27,7 @@ export class SzPlatformClient {
|
|
|
26
27
|
public emailConnector = new SzEmailConnector(this);
|
|
27
28
|
public smsConnector = new SzSmsConnector(this);
|
|
28
29
|
public pushNotificationConnector = new SzPushNotificationConnector(this);
|
|
30
|
+
public webPushConnector = new SzWebPushConnector(this);
|
|
29
31
|
public letterConnector = new SzLetterConnector(this);
|
|
30
32
|
|
|
31
33
|
constructor(authorizationStringArg?: string | ISzPlatformClientOptions) {
|
|
@@ -175,7 +177,10 @@ export class SzPlatformClient {
|
|
|
175
177
|
}
|
|
176
178
|
|
|
177
179
|
public async stop(): Promise<void> {
|
|
178
|
-
await
|
|
180
|
+
await Promise.all([
|
|
181
|
+
this.emailConnector.stop(),
|
|
182
|
+
this.webPushConnector.stop(),
|
|
183
|
+
]);
|
|
179
184
|
if (this.typedsocket) {
|
|
180
185
|
await this.typedsocket.stop();
|
|
181
186
|
}
|
package/ts/index.ts
CHANGED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import type { SzPlatformClient } from '../classes.platformclient.js';
|
|
2
|
+
import * as plugins from '../plugins.js';
|
|
3
|
+
|
|
4
|
+
export interface IServiceWebPushCredentials {
|
|
5
|
+
typedUrl: string;
|
|
6
|
+
credentialId: string;
|
|
7
|
+
credentialSecret: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface IServiceWebPushConfigurationStatus {
|
|
11
|
+
configured: boolean;
|
|
12
|
+
typedUrl?: string;
|
|
13
|
+
credentialIdConfigured: boolean;
|
|
14
|
+
credentialSecretConfigured: boolean;
|
|
15
|
+
missing: string[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface IServiceWebPushEnqueueOptions extends Omit<
|
|
19
|
+
plugins.servezoneInterfaces.requests.webpush.IReq_EnqueueWebPush['request'],
|
|
20
|
+
'auth' | 'owner'
|
|
21
|
+
> {}
|
|
22
|
+
|
|
23
|
+
export type TServiceWebPushCancellationTarget =
|
|
24
|
+
plugins.servezoneInterfaces.data.TWebPushCancellationTarget;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Credential-scoped Web Push delivery for a deployed service.
|
|
28
|
+
*
|
|
29
|
+
* This connector is separate from the legacy device-token push connector. It
|
|
30
|
+
* only accepts the service credential injected into the workload and never
|
|
31
|
+
* sends a caller-provided owner scope.
|
|
32
|
+
*/
|
|
33
|
+
export class SzWebPushConnector {
|
|
34
|
+
public platformClientRef: SzPlatformClient;
|
|
35
|
+
private webPushTypedSocket?: plugins.typedsocket.TypedSocket;
|
|
36
|
+
private webPushTypedSocketUrl?: string;
|
|
37
|
+
private webPushTypedSocketPromise?: Promise<plugins.typedsocket.TypedSocket>;
|
|
38
|
+
private webPushTypedSocketAbortController?: AbortController;
|
|
39
|
+
|
|
40
|
+
constructor(platformClientRefArg: SzPlatformClient) {
|
|
41
|
+
this.platformClientRef = platformClientRefArg;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public async getConfigurationStatus(): Promise<IServiceWebPushConfigurationStatus> {
|
|
45
|
+
const env = await this.readWebPushEnv();
|
|
46
|
+
const missing: string[] = [];
|
|
47
|
+
if (!env.typedUrl) missing.push('WEB_PUSH_TYPED_URL');
|
|
48
|
+
if (!env.credentialId) missing.push('WEB_PUSH_API_CREDENTIAL_ID');
|
|
49
|
+
if (!env.credentialSecret) missing.push('WEB_PUSH_API_CREDENTIAL_SECRET');
|
|
50
|
+
return {
|
|
51
|
+
configured: missing.length === 0,
|
|
52
|
+
typedUrl: env.typedUrl ? this.normalizeTypedSocketUrl(env.typedUrl) : undefined,
|
|
53
|
+
credentialIdConfigured: Boolean(env.credentialId),
|
|
54
|
+
credentialSecretConfigured: Boolean(env.credentialSecret),
|
|
55
|
+
missing,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public async getWebPushServiceStatus():
|
|
60
|
+
Promise<plugins.servezoneInterfaces.data.IWebPushServiceStatus> {
|
|
61
|
+
if (this.platformClientRef.debugMode) {
|
|
62
|
+
return {
|
|
63
|
+
ready: false,
|
|
64
|
+
bindingId: 'debug',
|
|
65
|
+
bindingStatus: 'disabled',
|
|
66
|
+
retiringVapidKeys: [],
|
|
67
|
+
maxPayloadBytes: 0,
|
|
68
|
+
maxTtlSeconds: 0,
|
|
69
|
+
contentEncoding: 'aes128gcm',
|
|
70
|
+
message: 'Web Push is disabled in platformclient debug mode',
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const { typedSocket, auth } = await this.getAuthenticatedClient();
|
|
74
|
+
const request = typedSocket.createTypedRequest<
|
|
75
|
+
plugins.servezoneInterfaces.requests.webpush.IReq_GetWebPushServiceStatus
|
|
76
|
+
>('getWebPushServiceStatus');
|
|
77
|
+
return await request.fire({ auth });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public async getWebPushPublicKey(): Promise<string> {
|
|
81
|
+
const status = await this.getWebPushServiceStatus();
|
|
82
|
+
if (!status.ready || !status.activeVapidKey?.publicKey) {
|
|
83
|
+
throw new Error(status.message || 'Web Push is not ready');
|
|
84
|
+
}
|
|
85
|
+
return status.activeVapidKey.publicKey;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
public async enqueueWebPush(
|
|
89
|
+
optionsArg: IServiceWebPushEnqueueOptions,
|
|
90
|
+
): Promise<plugins.servezoneInterfaces.requests.webpush.IReq_EnqueueWebPush['response']> {
|
|
91
|
+
if (!optionsArg.idempotencyKey?.trim()) {
|
|
92
|
+
throw new Error('idempotencyKey is required');
|
|
93
|
+
}
|
|
94
|
+
if (!optionsArg.subscriptionId?.trim()) {
|
|
95
|
+
throw new Error('subscriptionId is required');
|
|
96
|
+
}
|
|
97
|
+
if (this.platformClientRef.debugMode) {
|
|
98
|
+
return {
|
|
99
|
+
accepted: true,
|
|
100
|
+
spoolItemId: 'debug',
|
|
101
|
+
message: 'Web Push accepted in platformclient debug mode',
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
const { typedSocket, auth } = await this.getAuthenticatedClient();
|
|
105
|
+
const request = typedSocket.createTypedRequest<
|
|
106
|
+
plugins.servezoneInterfaces.requests.webpush.IReq_EnqueueWebPush
|
|
107
|
+
>('enqueueWebPush');
|
|
108
|
+
return await request.fire({
|
|
109
|
+
auth,
|
|
110
|
+
idempotencyKey: optionsArg.idempotencyKey.trim(),
|
|
111
|
+
subscriptionId: optionsArg.subscriptionId.trim(),
|
|
112
|
+
subscription: optionsArg.subscription,
|
|
113
|
+
vapidKeyId: optionsArg.vapidKeyId,
|
|
114
|
+
payload: optionsArg.payload,
|
|
115
|
+
ttlSeconds: optionsArg.ttlSeconds,
|
|
116
|
+
urgency: optionsArg.urgency,
|
|
117
|
+
collapseKey: optionsArg.collapseKey,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public async cancelWebPush(
|
|
122
|
+
targetArg: TServiceWebPushCancellationTarget,
|
|
123
|
+
): Promise<plugins.servezoneInterfaces.requests.webpush.IReq_CancelWebPush['response']> {
|
|
124
|
+
if (targetArg.type === 'spoolItem' && !targetArg.spoolItemId?.trim()) {
|
|
125
|
+
throw new Error('spoolItemId is required');
|
|
126
|
+
}
|
|
127
|
+
if (targetArg.type === 'subscription' && !targetArg.subscriptionId?.trim()) {
|
|
128
|
+
throw new Error('subscriptionId is required');
|
|
129
|
+
}
|
|
130
|
+
const target = targetArg.type === 'spoolItem'
|
|
131
|
+
? { type: 'spoolItem' as const, spoolItemId: targetArg.spoolItemId.trim() }
|
|
132
|
+
: { type: 'subscription' as const, subscriptionId: targetArg.subscriptionId.trim() };
|
|
133
|
+
if (this.platformClientRef.debugMode) {
|
|
134
|
+
return {
|
|
135
|
+
success: true,
|
|
136
|
+
cancelledCount: 0,
|
|
137
|
+
alreadyTerminalCount: 0,
|
|
138
|
+
message: 'Web Push cancellation accepted in platformclient debug mode',
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
const { typedSocket, auth } = await this.getAuthenticatedClient();
|
|
142
|
+
const request = typedSocket.createTypedRequest<
|
|
143
|
+
plugins.servezoneInterfaces.requests.webpush.IReq_CancelWebPush
|
|
144
|
+
>('cancelWebPush');
|
|
145
|
+
return await request.fire({ auth, target });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
public async getWebPushDeliveryStatus(
|
|
149
|
+
spoolItemIdArg: string,
|
|
150
|
+
): Promise<plugins.servezoneInterfaces.data.IWebPushDeliveryStatus | undefined> {
|
|
151
|
+
const spoolItemId = String(spoolItemIdArg || '').trim();
|
|
152
|
+
if (!spoolItemId) {
|
|
153
|
+
throw new Error('spoolItemId is required');
|
|
154
|
+
}
|
|
155
|
+
if (this.platformClientRef.debugMode) {
|
|
156
|
+
return {
|
|
157
|
+
spoolItemId,
|
|
158
|
+
state: 'queued',
|
|
159
|
+
attempts: 0,
|
|
160
|
+
acceptedAt: 0,
|
|
161
|
+
updatedAt: 0,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
const { typedSocket, auth } = await this.getAuthenticatedClient();
|
|
165
|
+
const request = typedSocket.createTypedRequest<
|
|
166
|
+
plugins.servezoneInterfaces.requests.webpush.IReq_GetWebPushDeliveryStatus
|
|
167
|
+
>('getWebPushDeliveryStatus');
|
|
168
|
+
const result = await request.fire({ auth, spoolItemId });
|
|
169
|
+
return result.delivery;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
public async stop(): Promise<void> {
|
|
173
|
+
const socket = this.webPushTypedSocket;
|
|
174
|
+
const socketPromise = this.webPushTypedSocketPromise;
|
|
175
|
+
this.webPushTypedSocket = undefined;
|
|
176
|
+
this.webPushTypedSocketPromise = undefined;
|
|
177
|
+
this.webPushTypedSocketUrl = undefined;
|
|
178
|
+
this.webPushTypedSocketAbortController?.abort();
|
|
179
|
+
this.webPushTypedSocketAbortController = undefined;
|
|
180
|
+
if (socket) {
|
|
181
|
+
await socket.stop();
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (socketPromise) {
|
|
185
|
+
try {
|
|
186
|
+
const pendingSocket = await socketPromise;
|
|
187
|
+
await pendingSocket.stop();
|
|
188
|
+
} catch {
|
|
189
|
+
// A failed or aborted connection leaves no socket to close.
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
private async getAuthenticatedClient(): Promise<{
|
|
195
|
+
typedSocket: plugins.typedsocket.TypedSocket;
|
|
196
|
+
auth: plugins.servezoneInterfaces.requests.webpush.IWebPushAppCredentialAuth;
|
|
197
|
+
}> {
|
|
198
|
+
const credentials = await this.getCredentials();
|
|
199
|
+
return {
|
|
200
|
+
typedSocket: await this.getWebPushTypedSocket(credentials.typedUrl),
|
|
201
|
+
auth: {
|
|
202
|
+
credentialId: credentials.credentialId,
|
|
203
|
+
credentialSecret: credentials.credentialSecret,
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
private async getCredentials(): Promise<IServiceWebPushCredentials> {
|
|
209
|
+
const env = await this.readWebPushEnv();
|
|
210
|
+
if (!env.typedUrl) throw new Error('WEB_PUSH_TYPED_URL is required for Web Push');
|
|
211
|
+
if (!env.credentialId) {
|
|
212
|
+
throw new Error('WEB_PUSH_API_CREDENTIAL_ID is required for Web Push');
|
|
213
|
+
}
|
|
214
|
+
if (!env.credentialSecret) {
|
|
215
|
+
throw new Error('WEB_PUSH_API_CREDENTIAL_SECRET is required for Web Push');
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
typedUrl: env.typedUrl,
|
|
219
|
+
credentialId: env.credentialId,
|
|
220
|
+
credentialSecret: env.credentialSecret,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
private async readWebPushEnv(): Promise<{
|
|
225
|
+
typedUrl?: string;
|
|
226
|
+
credentialId?: string;
|
|
227
|
+
credentialSecret?: string;
|
|
228
|
+
}> {
|
|
229
|
+
const directEnv = this.normalizeCredentialBundle({
|
|
230
|
+
typedUrl: await this.platformClientRef.getConfiguredEnvVar('WEB_PUSH_TYPED_URL'),
|
|
231
|
+
credentialId: await this.platformClientRef.getConfiguredEnvVar(
|
|
232
|
+
'WEB_PUSH_API_CREDENTIAL_ID',
|
|
233
|
+
),
|
|
234
|
+
credentialSecret: await this.platformClientRef.getConfiguredEnvVar(
|
|
235
|
+
'WEB_PUSH_API_CREDENTIAL_SECRET',
|
|
236
|
+
),
|
|
237
|
+
});
|
|
238
|
+
if (this.hasCredentialBundleValue(directEnv)) {
|
|
239
|
+
return directEnv;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const bindingCredentialBundles: Array<Partial<IServiceWebPushCredentials>> = [];
|
|
243
|
+
for (const binding of this.platformClientRef.platformBindings || []) {
|
|
244
|
+
if (
|
|
245
|
+
binding.capability !== 'pushnotification'
|
|
246
|
+
|| binding.desiredState !== 'enabled'
|
|
247
|
+
|| binding.status !== 'ready'
|
|
248
|
+
) {
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
for (const credential of binding.credentials || []) {
|
|
252
|
+
const credentialBundle = this.normalizeCredentialBundle({
|
|
253
|
+
typedUrl: credential.env?.WEB_PUSH_TYPED_URL,
|
|
254
|
+
credentialId: credential.env?.WEB_PUSH_API_CREDENTIAL_ID,
|
|
255
|
+
credentialSecret: credential.env?.WEB_PUSH_API_CREDENTIAL_SECRET,
|
|
256
|
+
});
|
|
257
|
+
if (this.hasCredentialBundleValue(credentialBundle)) {
|
|
258
|
+
bindingCredentialBundles.push(credentialBundle);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (bindingCredentialBundles.length > 1) {
|
|
264
|
+
throw new Error(
|
|
265
|
+
'Multiple ready Web Push credential bundles are configured; exactly one is required',
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
return bindingCredentialBundles[0] || {};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
private normalizeCredentialBundle(bundleArg: {
|
|
272
|
+
typedUrl?: string;
|
|
273
|
+
credentialId?: string;
|
|
274
|
+
credentialSecret?: string;
|
|
275
|
+
}): Partial<IServiceWebPushCredentials> {
|
|
276
|
+
const typedUrl = this.normalizeConfigValue(bundleArg.typedUrl);
|
|
277
|
+
return {
|
|
278
|
+
typedUrl: typedUrl ? this.normalizeTypedSocketUrl(typedUrl) || undefined : undefined,
|
|
279
|
+
credentialId: this.normalizeConfigValue(bundleArg.credentialId),
|
|
280
|
+
credentialSecret: this.normalizeConfigValue(bundleArg.credentialSecret),
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
private hasCredentialBundleValue(bundleArg: Partial<IServiceWebPushCredentials>): boolean {
|
|
285
|
+
return Boolean(
|
|
286
|
+
bundleArg.typedUrl
|
|
287
|
+
|| bundleArg.credentialId
|
|
288
|
+
|| bundleArg.credentialSecret,
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
private normalizeConfigValue(valueArg?: string): string | undefined {
|
|
293
|
+
const value = valueArg?.trim();
|
|
294
|
+
return value || undefined;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
private async getWebPushTypedSocket(urlArg: string): Promise<plugins.typedsocket.TypedSocket> {
|
|
298
|
+
const normalizedUrl = this.normalizeTypedSocketUrl(urlArg);
|
|
299
|
+
if (this.webPushTypedSocket && this.webPushTypedSocketUrl === normalizedUrl) {
|
|
300
|
+
return this.webPushTypedSocket;
|
|
301
|
+
}
|
|
302
|
+
if (this.webPushTypedSocketPromise && this.webPushTypedSocketUrl === normalizedUrl) {
|
|
303
|
+
return await this.webPushTypedSocketPromise;
|
|
304
|
+
}
|
|
305
|
+
if (this.webPushTypedSocket || this.webPushTypedSocketPromise) {
|
|
306
|
+
await this.stop();
|
|
307
|
+
}
|
|
308
|
+
this.webPushTypedSocketUrl = normalizedUrl;
|
|
309
|
+
const abortController = new AbortController();
|
|
310
|
+
this.webPushTypedSocketAbortController = abortController;
|
|
311
|
+
const socketPromise = plugins.typedsocket.TypedSocket.createClient(
|
|
312
|
+
this.platformClientRef.typedrouter,
|
|
313
|
+
normalizedUrl,
|
|
314
|
+
{ autoReconnect: true, abortSignal: abortController.signal },
|
|
315
|
+
);
|
|
316
|
+
this.webPushTypedSocketPromise = socketPromise;
|
|
317
|
+
try {
|
|
318
|
+
const socket = await socketPromise;
|
|
319
|
+
if (
|
|
320
|
+
this.webPushTypedSocketPromise === socketPromise
|
|
321
|
+
&& this.webPushTypedSocketUrl === normalizedUrl
|
|
322
|
+
) {
|
|
323
|
+
this.webPushTypedSocket = socket;
|
|
324
|
+
} else {
|
|
325
|
+
await socket.stop();
|
|
326
|
+
}
|
|
327
|
+
return socket;
|
|
328
|
+
} catch (error) {
|
|
329
|
+
if (this.webPushTypedSocketPromise === socketPromise) {
|
|
330
|
+
this.webPushTypedSocketPromise = undefined;
|
|
331
|
+
this.webPushTypedSocketUrl = undefined;
|
|
332
|
+
this.webPushTypedSocketAbortController = undefined;
|
|
333
|
+
}
|
|
334
|
+
throw error;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
private normalizeTypedSocketUrl(urlArg: string): string {
|
|
339
|
+
return urlArg.trim().replace(/\/typedrequest\/?$/, '').replace(/\/+$/, '');
|
|
340
|
+
}
|
|
341
|
+
}
|