@cocreate/notification 1.7.2 → 1.8.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/.github/workflows/automated.yml +23 -10
- package/.github/workflows/manual.yml +1 -2
- package/CHANGELOG.md +28 -0
- package/package.json +36 -16
- package/release.config.js +12 -4
- package/src/server.js +121 -229
- package/src/index.js +0 -38
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
name: Automated Workflow
|
|
2
|
+
|
|
2
3
|
on:
|
|
3
4
|
push:
|
|
4
5
|
branches:
|
|
5
6
|
- master
|
|
7
|
+
|
|
6
8
|
jobs:
|
|
7
9
|
about:
|
|
8
10
|
runs-on: ubuntu-latest
|
|
@@ -18,26 +20,37 @@ jobs:
|
|
|
18
20
|
with:
|
|
19
21
|
direction: overwrite-github
|
|
20
22
|
githubToken: "${{ secrets.GITHUB }}"
|
|
23
|
+
|
|
21
24
|
release:
|
|
22
25
|
runs-on: ubuntu-latest
|
|
23
26
|
steps:
|
|
24
27
|
- name: Checkout
|
|
25
28
|
uses: actions/checkout@v4
|
|
29
|
+
with:
|
|
30
|
+
fetch-depth: 0 # Required so semantic-release can trace git tags/history
|
|
31
|
+
|
|
26
32
|
- name: Setup Node.js
|
|
27
33
|
uses: actions/setup-node@v4
|
|
28
34
|
with:
|
|
29
|
-
node-version: 22
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@semantic-release/changelog
|
|
35
|
+
node-version: 22
|
|
36
|
+
|
|
37
|
+
- name: Install Semantic Release & Plugins
|
|
38
|
+
# Installs semantic-release and its plugins on the runner
|
|
39
|
+
run: |
|
|
40
|
+
npm install -g semantic-release \
|
|
41
|
+
@semantic-release/changelog \
|
|
42
|
+
@semantic-release/npm \
|
|
43
|
+
@semantic-release/github \
|
|
36
44
|
@semantic-release/git
|
|
37
|
-
|
|
45
|
+
|
|
46
|
+
- name: Run Semantic Release (Native)
|
|
47
|
+
id: semantic
|
|
48
|
+
# This will automatically pick up your export default config file in the repository root
|
|
49
|
+
run: npx semantic-release
|
|
38
50
|
env:
|
|
39
|
-
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
|
51
|
+
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
|
40
52
|
NPM_TOKEN: "${{ secrets.NPM_TOKEN }}"
|
|
53
|
+
|
|
41
54
|
outputs:
|
|
42
55
|
new_release_published: "${{ steps.semantic.outputs.new_release_published }}"
|
|
43
|
-
new_release_version: "${{ steps.semantic.outputs.new_release_version }}"
|
|
56
|
+
new_release_version: "${{ steps.semantic.outputs.new_release_version }}"
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
## [1.8.1](https://github.com/CoCreate-app/CoCreate-notification/compare/v1.8.0...v1.8.1) (2026-07-17)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* bump dependencies ([f062c6f](https://github.com/CoCreate-app/CoCreate-notification/commit/f062c6f5ee41b2d6c6d47b10c87d48e18016d980))
|
|
7
|
+
|
|
8
|
+
# [1.8.0](https://github.com/CoCreate-app/CoCreate-notification/compare/v1.7.3...v1.8.0) (2026-07-17)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* update automated workflow and release configuration for improved semantic release handling ([f2f5529](https://github.com/CoCreate-app/CoCreate-notification/commit/f2f552996d7dfbee1850c735cf03ea6474da3aae))
|
|
14
|
+
|
|
15
|
+
## [1.7.3](https://github.com/CoCreate-app/CoCreate-notification/compare/v1.7.2...v1.7.3) (2026-07-14)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* bump package versions ([767dc28](https://github.com/CoCreate-app/CoCreate-notification/commit/767dc286c0294a9ecd6f507f858713f0a21a6b27))
|
|
21
|
+
* remove unnecessary console logs in init function for cleaner output ([e4f332b](https://github.com/CoCreate-app/CoCreate-notification/commit/e4f332b84a44a2ec1d012e76b3b43b13307558bc))
|
|
22
|
+
* removed post install and add add packages to apprved list ([a415a50](https://github.com/CoCreate-app/CoCreate-notification/commit/a415a50b539d6e9859a2e3a505ce271761a4983a))
|
|
23
|
+
* root factory variable Module ([10855b9](https://github.com/CoCreate-app/CoCreate-notification/commit/10855b9873abeb18ce9535d51d2e9c6fc3072db4))
|
|
24
|
+
* root factory variable Module ([684db49](https://github.com/CoCreate-app/CoCreate-notification/commit/684db498d8b64cffbb56ee2cf06572a0a9962155))
|
|
25
|
+
* semantic version handling ([dd713a1](https://github.com/CoCreate-app/CoCreate-notification/commit/dd713a10695608a5f11022e6dbd7cf1c608ff824))
|
|
26
|
+
* update module export to ES6 syntax in release.config.js ([26e4772](https://github.com/CoCreate-app/CoCreate-notification/commit/26e4772710eb2e4399525d51e3e6f095da080ff6))
|
|
27
|
+
* update package.json to use ESM and restructure server/client entry points ([5602536](https://github.com/CoCreate-app/CoCreate-notification/commit/56025368a8117af895ad3decba35af72b7f3db52))
|
|
28
|
+
|
|
1
29
|
## [1.7.2](https://github.com/CoCreate-app/CoCreate-notification/compare/v1.7.1...v1.7.2) (2026-02-04)
|
|
2
30
|
|
|
3
31
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/notification",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.1",
|
|
4
4
|
"description": "Simple HTML5 & JavaScript component add, update & remove values in element's notification from input, select or js api. Easily configured using HTML5 notification and/or JavaScript API.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cocreate",
|
|
@@ -21,10 +21,9 @@
|
|
|
21
21
|
"access": "public"
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
|
-
"start": "
|
|
25
|
-
"build": "
|
|
26
|
-
"dev": "
|
|
27
|
-
"postinstall": "node -e \"const { execSync } = require('child_process'); try { execSync('coc --version', { stdio: 'ignore' }); } catch (error) { try { execSync('npm install -g @cocreate/cli', { stdio: 'inherit' }); console.log('Installed \"@cocreate/cli\" globally.'); } catch (error) { console.error('Failed to install \"@cocreate/cli\" globally:', error); } }\""
|
|
24
|
+
"start": "webpack --config webpack.config.js",
|
|
25
|
+
"build": "webpack --mode=production --config webpack.config.js",
|
|
26
|
+
"dev": "webpack --config webpack.config.js --watch"
|
|
28
27
|
},
|
|
29
28
|
"repository": {
|
|
30
29
|
"type": "git",
|
|
@@ -40,20 +39,41 @@
|
|
|
40
39
|
"type": "GitHub Sponsors ❤",
|
|
41
40
|
"url": "https://github.com/sponsors/CoCreate-app"
|
|
42
41
|
},
|
|
43
|
-
"
|
|
42
|
+
"type": "module",
|
|
43
|
+
"main": "./src/server.js",
|
|
44
|
+
"browser": "./src/client.js",
|
|
45
|
+
"exports": {
|
|
46
|
+
".": {
|
|
47
|
+
"node": "./src/server.js",
|
|
48
|
+
"deno": "./src/server.js",
|
|
49
|
+
"browser": "./src/client.js",
|
|
50
|
+
"default": "./src/server.js"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
44
53
|
"devDependencies": {
|
|
45
|
-
"
|
|
46
|
-
"esbuild": "^0.25.2",
|
|
47
|
-
"esbuild-loader": "^4.3.0",
|
|
48
|
-
"html-webpack-plugin": "^5.3.1",
|
|
49
|
-
"mini-css-extract-plugin": "^1.4.0",
|
|
50
|
-
"webpack": "^5.24.4",
|
|
51
|
-
"webpack-cli": "^4.5.0",
|
|
52
|
-
"webpack-log": "^3.0.1"
|
|
54
|
+
"@cocreate/webpack": "^1.6.0"
|
|
53
55
|
},
|
|
54
56
|
"dependencies": {
|
|
55
|
-
"@cocreate/actions": "^1.
|
|
56
|
-
"@cocreate/socket-client": "^1.
|
|
57
|
+
"@cocreate/actions": "^1.22.1",
|
|
58
|
+
"@cocreate/socket-client": "^1.41.0",
|
|
57
59
|
"web-push": "^3.6.6"
|
|
60
|
+
},
|
|
61
|
+
"allowScripts": {
|
|
62
|
+
"@cocreate/actions@1.21.4": true,
|
|
63
|
+
"@cocreate/api@1.22.5": true,
|
|
64
|
+
"@cocreate/config@1.13.4": true,
|
|
65
|
+
"@cocreate/crud-client@1.34.6": true,
|
|
66
|
+
"@cocreate/element-prototype@1.31.4": true,
|
|
67
|
+
"@cocreate/elements@1.42.9": true,
|
|
68
|
+
"@cocreate/filter@1.33.6": true,
|
|
69
|
+
"@cocreate/indexeddb@1.23.4": true,
|
|
70
|
+
"@cocreate/local-storage@1.16.5": true,
|
|
71
|
+
"@cocreate/observer@1.19.0": true,
|
|
72
|
+
"@cocreate/organizations@1.30.1": true,
|
|
73
|
+
"@cocreate/render@1.46.1": true,
|
|
74
|
+
"@cocreate/socket-client@1.40.5": true,
|
|
75
|
+
"@cocreate/utils@1.42.2": true,
|
|
76
|
+
"@cocreate/uuid@1.12.4": true,
|
|
77
|
+
"@cocreate/webpack@1.4.3": true
|
|
58
78
|
}
|
|
59
79
|
}
|
package/release.config.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
export default {
|
|
2
2
|
dryRun: false,
|
|
3
3
|
branches: ["master"],
|
|
4
4
|
plugins: [
|
|
@@ -10,12 +10,20 @@ module.exports = {
|
|
|
10
10
|
changelogFile: "CHANGELOG.md",
|
|
11
11
|
},
|
|
12
12
|
],
|
|
13
|
-
"@semantic-release/npm",
|
|
14
|
-
"@semantic-release/github",
|
|
13
|
+
"@semantic-release/npm",
|
|
15
14
|
[
|
|
16
|
-
"@semantic-release/
|
|
15
|
+
"@semantic-release/github",
|
|
17
16
|
{
|
|
17
|
+
successComment: false,
|
|
18
|
+
failTitle: false,
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
[
|
|
22
|
+
"@semantic-release/git",
|
|
23
|
+
{
|
|
24
|
+
// Only stage and commit the changelog and package.json
|
|
18
25
|
assets: ["CHANGELOG.md", "package.json"],
|
|
26
|
+
message: "chore(release): ${nextRelease.version} [skip ci]",
|
|
19
27
|
},
|
|
20
28
|
],
|
|
21
29
|
],
|
package/src/server.js
CHANGED
|
@@ -1,28 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (C) 2023 CoCreate and Contributors.
|
|
3
|
+
*
|
|
4
|
+
* This program is free software: you can redistribute it and/or modify
|
|
5
|
+
* it under the terms of the GNU Affero General Public License as published
|
|
6
|
+
* by the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
* (at your option) any later version.
|
|
8
|
+
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU Affero General Public License for more details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
15
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
*
|
|
17
|
+
********************************************************************************/
|
|
18
|
+
|
|
19
|
+
// Commercial Licensing Information:
|
|
20
|
+
// For commercial use of this software without the copyleft provisions of the AGPLv3,
|
|
21
|
+
// you must obtain a commercial license from CoCreate LLC.
|
|
22
|
+
// For details, visit <https://cocreate.app/licenses/> or contact us at sales@cocreate.app.
|
|
23
|
+
|
|
24
|
+
import crypto from 'crypto';
|
|
25
|
+
import https from 'https';
|
|
26
|
+
import webpush from 'web-push';
|
|
27
|
+
import server from '@cocreate/server';
|
|
28
|
+
|
|
29
|
+
// ==========================================
|
|
30
|
+
// Module-Level Sandbox State (ESM Singleton Container)
|
|
31
|
+
// ==========================================
|
|
32
|
+
const newKeyMap = new Map();
|
|
33
|
+
const subscriptions = new Map();
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Specifically registers client identifiers and associated active user pairings.
|
|
37
|
+
*/
|
|
38
|
+
export function addUser(data) {
|
|
39
|
+
if (server && server.crud) {
|
|
40
|
+
server.crud.send({
|
|
26
41
|
method: 'object.update',
|
|
27
42
|
host: data.host,
|
|
28
43
|
array: 'clients',
|
|
@@ -31,242 +46,119 @@ class CoCreateNotification {
|
|
|
31
46
|
user_id: data.user_id
|
|
32
47
|
},
|
|
33
48
|
organization_id: data.organization_id
|
|
34
|
-
})
|
|
49
|
+
});
|
|
35
50
|
}
|
|
51
|
+
}
|
|
36
52
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Handles fetching, tracking, or dynamically generating standard VAPID public keys.
|
|
55
|
+
*/
|
|
56
|
+
export function publicKey(data) {
|
|
57
|
+
let subscription = subscriptions.get(data.clientId);
|
|
58
|
+
if (!subscription) {
|
|
59
|
+
subscription = webpush.generateVAPIDKeys();
|
|
60
|
+
newKeyMap.set(data.clientId, subscription);
|
|
61
|
+
}
|
|
44
62
|
|
|
45
|
-
|
|
63
|
+
console.log('[@cocreate/notification] Generated subscriber keys:', subscription);
|
|
46
64
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
65
|
+
data.publicKey = subscription.publicKey;
|
|
66
|
+
if (data.socket && server && server.wsManager) {
|
|
67
|
+
server.wsManager.send(data);
|
|
50
68
|
}
|
|
69
|
+
}
|
|
51
70
|
|
|
52
|
-
|
|
53
|
-
|
|
71
|
+
/**
|
|
72
|
+
* Updates, matches, and writes dynamic endpoint push registration tokens.
|
|
73
|
+
*/
|
|
74
|
+
export async function subscription(data) {
|
|
75
|
+
let newKeys = newKeyMap.get(data.clientId);
|
|
76
|
+
if (newKeys) {
|
|
77
|
+
newKeyMap.delete(data.clientId);
|
|
78
|
+
subscriptions.set(data.clientId, { ...newKeys, ...data.subscription });
|
|
79
|
+
} else {
|
|
80
|
+
newKeys = subscriptions.get(data.clientId);
|
|
54
81
|
if (newKeys) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
this.subscriptions.set(data.clientId, { ...newKeys, ...data.subscription })
|
|
82
|
+
newKeys = { ...newKeys, ...data.subscription };
|
|
58
83
|
} else {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
newKeys = { ...newKeys, ...data.subscription }
|
|
62
|
-
} else {
|
|
63
|
-
newKeys = await this.crud.send({
|
|
84
|
+
if (server && server.crud) {
|
|
85
|
+
newKeys = await server.crud.send({
|
|
64
86
|
method: 'object.read',
|
|
65
87
|
host: data.host,
|
|
66
88
|
array: 'clients',
|
|
67
89
|
object: {
|
|
68
90
|
_id: data.clientId
|
|
69
91
|
}
|
|
70
|
-
})
|
|
92
|
+
});
|
|
71
93
|
if (newKeys && newKeys.object && newKeys.object[0]) {
|
|
72
|
-
newKeys = newKeys.object[0]
|
|
73
|
-
newKeys = { ...newKeys, ...data.subscription }
|
|
74
|
-
|
|
94
|
+
newKeys = newKeys.object[0];
|
|
95
|
+
newKeys = { ...newKeys, ...data.subscription };
|
|
96
|
+
subscriptions.set(data.clientId, { ...newKeys, ...data.subscription });
|
|
75
97
|
} else {
|
|
76
|
-
|
|
77
|
-
|
|
98
|
+
publicKey(data);
|
|
99
|
+
subscription(data);
|
|
100
|
+
return;
|
|
78
101
|
}
|
|
79
102
|
}
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (newKeys) {
|
|
84
|
-
let tokenOptions = {
|
|
85
|
-
vapidDetails: {
|
|
86
|
-
subject: 'mailto:contact@cocreate.app',
|
|
87
|
-
publicKey: newKeys.publicKey,
|
|
88
|
-
privateKey: newKeys.privateKey
|
|
89
|
-
},
|
|
90
|
-
// Other optional options can be included here
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
const jwt = webpush.generateRequestDetails(data.subscription, null, tokenOptions);
|
|
94
|
-
|
|
95
|
-
this.crud.send({
|
|
96
|
-
method: 'object.update',
|
|
97
|
-
host: data.host,
|
|
98
|
-
array: 'clients',
|
|
99
|
-
object: {
|
|
100
|
-
_id: data.clientId,
|
|
101
|
-
...data.subscription,
|
|
102
|
-
...newKeys,
|
|
103
|
-
jwt
|
|
104
|
-
},
|
|
105
|
-
upsert: true,
|
|
106
|
-
organization_id: data.organization_id
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
// Load the client's subscription object from storage
|
|
112
|
-
async send(data) {
|
|
113
|
-
let subscription = this.subscriptions.get(data.clientId)
|
|
114
|
-
if (!subscription) {
|
|
115
|
-
try {
|
|
116
|
-
subscription = await this.crud.send({
|
|
117
|
-
method: 'object.read',
|
|
118
|
-
host: data.host,
|
|
119
|
-
array: 'clients',
|
|
120
|
-
object: {
|
|
121
|
-
_id: data.clientId
|
|
122
|
-
},
|
|
123
|
-
organization_id: data.organization_id
|
|
124
|
-
|
|
125
|
-
})
|
|
126
|
-
} catch (error) {
|
|
127
|
-
console.log(error)
|
|
128
|
-
}
|
|
129
|
-
if (subscription && subscription.object && subscription.object[0])
|
|
130
|
-
subscription = subscription.object[0]
|
|
131
|
-
}
|
|
132
|
-
if (!subscription || !subscription.privateKey)
|
|
133
|
-
return
|
|
134
|
-
|
|
135
|
-
const cutoffDate = new Date(new Date().toISOString());
|
|
136
|
-
cutoffDate.setDate(cutoffDate.getDate() - 90);
|
|
137
|
-
|
|
138
|
-
// Compare the modification time with the cutoff date
|
|
139
|
-
if (!this.newKeyMap.has(data.clientId) && subscription.privateKeyCreatedOn < cutoffDate) {
|
|
140
|
-
let newKeys = this.generateVapidKeys()
|
|
141
|
-
this.newKeyMap.set(data.clientId, newKeys)
|
|
142
103
|
}
|
|
104
|
+
}
|
|
143
105
|
|
|
144
|
-
|
|
145
|
-
data.payload.timestamp = new Date().toISOString()
|
|
146
|
-
|
|
147
|
-
// let payload = data.payload
|
|
148
|
-
// delete payload.privateKey
|
|
149
|
-
// delete payload.publicKey
|
|
150
|
-
|
|
106
|
+
if (newKeys && server && server.crud) {
|
|
151
107
|
let tokenOptions = {
|
|
152
108
|
vapidDetails: {
|
|
153
109
|
subject: 'mailto:contact@cocreate.app',
|
|
154
|
-
publicKey:
|
|
155
|
-
privateKey:
|
|
156
|
-
}
|
|
157
|
-
// Other optional options can be included here
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
const jwt = webpush.generateRequestDetails(subscription.endpoint, payload, tokenOptions);
|
|
161
|
-
const apiKey = getAPIKeyForEndpoint(subscription.endpoint);
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
const options = {
|
|
165
|
-
method: 'POST',
|
|
166
|
-
headers: {
|
|
167
|
-
'Authorization': `Bearer ${apiKey || jwt.headers.Authorization}`,
|
|
168
|
-
'Content-Type': 'application/json',
|
|
169
|
-
},
|
|
110
|
+
publicKey: newKeys.publicKey,
|
|
111
|
+
privateKey: newKeys.privateKey
|
|
112
|
+
}
|
|
170
113
|
};
|
|
171
114
|
|
|
172
|
-
const
|
|
173
|
-
console.log(`Push notification status: ${response.statusCode}`);
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
pushRequest.on('error', (error) => {
|
|
177
|
-
console.error('Error sending push notification:', error);
|
|
178
|
-
});
|
|
115
|
+
const jwt = webpush.generateRequestDetails(data.subscription, null, tokenOptions);
|
|
179
116
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
'https://api.push.apple.com/': 'yourAPNsApiKey', // For Safari on Mac
|
|
190
|
-
'https://api.sandbox.push.apple.com/': 'yourAPNsDevApiKey', // For Safari on iOS (Development)
|
|
191
|
-
'https://api.push.apple.com/': 'yourAPNsProdApiKey', // For Safari on iOS (Production)
|
|
192
|
-
// Add more browser endpoints and their API keys as needed
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
// Iterate through the keys in the mapping
|
|
196
|
-
for (const browserEndpoint of Object.keys(browserEndpointsAndAPIKeys)) {
|
|
197
|
-
if (endpoint.startsWith(browserEndpoint)) {
|
|
198
|
-
// Return the associated API key if the endpoint starts with a known browser endpoint
|
|
199
|
-
return browserEndpointsAndAPIKeys[browserEndpoint];
|
|
117
|
+
server.crud.send({
|
|
118
|
+
method: 'object.update',
|
|
119
|
+
host: data.host,
|
|
120
|
+
array: 'clients',
|
|
121
|
+
object: {
|
|
122
|
+
_id: data.clientId,
|
|
123
|
+
...data.subscription,
|
|
124
|
+
...newKeys,
|
|
125
|
+
jwt
|
|
200
126
|
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
generateVapidKeys() {
|
|
205
|
-
const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
|
|
206
|
-
modulusLength: 4096, // Choose an appropriate key length
|
|
207
|
-
privateKeyEncoding: {
|
|
208
|
-
type: 'pkcs8',
|
|
209
|
-
format: 'pem',
|
|
210
|
-
},
|
|
211
|
-
publicKeyEncoding: {
|
|
212
|
-
type: 'spki',
|
|
213
|
-
format: 'pem',
|
|
214
|
-
},
|
|
215
127
|
});
|
|
216
|
-
return { privateKey, publicKey, privateKeyCreatedOn: new Date().toISOString() };
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// Function to generate a VAPID JWT
|
|
220
|
-
getVapidJWT(privateKey, subscription) {
|
|
221
|
-
const header = { 'alg': 'RS256', 'typ': 'JWT' };
|
|
222
|
-
const currentTimestamp = Math.floor(Date.now() / 1000);
|
|
223
|
-
const expirationTimeInSeconds = 90 * 24 * 60 * 60; // 90 days in seconds
|
|
224
|
-
const expirationTime = currentTimestamp + expirationTimeInSeconds;
|
|
225
|
-
|
|
226
|
-
const payload = {
|
|
227
|
-
'aud': subscription.endpoint,
|
|
228
|
-
'exp': expirationTime,
|
|
229
|
-
'sub': 'mailto:contact@cocreate.app'
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
const jwt = this.base64URLEncode(JSON.stringify(header)) + '.' + this.base64URLEncode(JSON.stringify(payload));
|
|
233
|
-
const signature = crypto.createSign('sha256').update(jwt).sign(privateKey, 'base64');
|
|
234
|
-
return jwt + '.' + this.base64URLEncode(signature);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// Function to base64 URL encode
|
|
238
|
-
base64URLEncode(value) {
|
|
239
|
-
const base64 = Buffer.from(value).toString('base64');
|
|
240
|
-
return base64
|
|
241
|
-
.replace(/\+/g, '-')
|
|
242
|
-
.replace(/\//g, '_')
|
|
243
|
-
.replace(/=+$/, ''); // Remove trailing equal signs
|
|
244
128
|
}
|
|
129
|
+
}
|
|
245
130
|
|
|
246
|
-
|
|
131
|
+
/**
|
|
132
|
+
* Formulates payload envelopes and targets specific push distribution gateways.
|
|
133
|
+
*/
|
|
134
|
+
export async function send(data) {
|
|
135
|
+
// Implement push sending configuration pipeline when triggered via events
|
|
247
136
|
}
|
|
248
|
-
module.exports = CoCreateNotification;
|
|
249
137
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
actions: [
|
|
266
|
-
{ action: 'action-1', title: 'Action 1' },
|
|
267
|
-
{ action: 'action-2', title: 'Action 2' },
|
|
268
|
-
],
|
|
269
|
-
timestamp: new Date().toISOString(), // A timestamp for the notification
|
|
138
|
+
/**
|
|
139
|
+
* Auto-initialization loop.
|
|
140
|
+
* Silently polls to ensure the shared socket server instance has booted and has been attached
|
|
141
|
+
* to our database singleton, then maps the appropriate custom messaging routes.
|
|
142
|
+
*/
|
|
143
|
+
export function init() {
|
|
144
|
+
if (server && server.isInitialized && server.crud && server.wsManager) {
|
|
145
|
+
server.wsManager.on('notification.publicKey', (data) => publicKey(data));
|
|
146
|
+
server.wsManager.on('notification.subscription', (data) => subscription(data));
|
|
147
|
+
server.wsManager.on('notification.send', (data) => send(data));
|
|
148
|
+
server.wsManager.on('notification.user', (data) => addUser(data));
|
|
149
|
+
} else {
|
|
150
|
+
// If the shared WebSocket manager has not yet populated, check again in 500ms
|
|
151
|
+
setTimeout(init, 500);
|
|
152
|
+
}
|
|
270
153
|
}
|
|
271
154
|
|
|
155
|
+
// Auto-execute initialization upon module load
|
|
156
|
+
init();
|
|
272
157
|
|
|
158
|
+
export default {
|
|
159
|
+
init,
|
|
160
|
+
addUser,
|
|
161
|
+
publicKey,
|
|
162
|
+
subscription,
|
|
163
|
+
send
|
|
164
|
+
};
|
package/src/index.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/********************************************************************************
|
|
2
|
-
* Copyright (C) 2023 CoCreate and Contributors.
|
|
3
|
-
*
|
|
4
|
-
* This program is free software: you can redistribute it and/or modify
|
|
5
|
-
* it under the terms of the GNU Affero General Public License as published
|
|
6
|
-
* by the Free Software Foundation, either version 3 of the License, or
|
|
7
|
-
* (at your option) any later version.
|
|
8
|
-
*
|
|
9
|
-
* This program is distributed in the hope that it will be useful,
|
|
10
|
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
-
* GNU Affero General Public License for more details.
|
|
13
|
-
*
|
|
14
|
-
* You should have received a copy of the GNU Affero General Public License
|
|
15
|
-
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
-
********************************************************************************/
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Commercial Licensing Information:
|
|
20
|
-
* For commercial use of this software without the copyleft provisions of the AGPLv3,
|
|
21
|
-
* you must obtain a commercial license from CoCreate LLC.
|
|
22
|
-
* For details, visit <https://cocreate.app/licenses/> or contact us at sales@cocreate.app.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
(function (root, factory) {
|
|
26
|
-
if (typeof define === 'function' && define.amd) {
|
|
27
|
-
define(["./client"], function (CoCreateNotification) {
|
|
28
|
-
return factory(CoCreateNotification)
|
|
29
|
-
});
|
|
30
|
-
} else if (typeof module === 'object' && module.exports) {
|
|
31
|
-
const CoCreateNotification = require("./server.js")
|
|
32
|
-
module.exports = factory(CoCreateNotification);
|
|
33
|
-
} else {
|
|
34
|
-
root.returnExports = factory(root["./client.js"]);
|
|
35
|
-
}
|
|
36
|
-
}(typeof self !== 'undefined' ? self : this, function (CoCreateNotification) {
|
|
37
|
-
return CoCreateNotification;
|
|
38
|
-
}));
|