@quintype/framework 7.33.6-fcm-fix-2.14 → 7.33.6-fcm-fix-2.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/client/start.js +0 -12
- package/package.json +1 -1
- package/server/handlers/fcm-registration-handler.js +2 -11
- package/server/routes.js +3 -3
- package/test/integration/sketches-proxy-test.js +351 -351
- package/client/impl/fcm.js +0 -53
package/README.md
CHANGED
|
@@ -171,7 +171,7 @@ startApp(renderApplication,
|
|
|
171
171
|
```js
|
|
172
172
|
isomorphicRoutes(app, {
|
|
173
173
|
...
|
|
174
|
-
|
|
174
|
+
fcmServiceCreds: (config) => <ServiceCreds> || fcmServiceCreds: <ServiceCreds> {(function|object)}
|
|
175
175
|
...
|
|
176
176
|
});
|
|
177
177
|
|
package/client/start.js
CHANGED
|
@@ -17,7 +17,6 @@ import { IsomorphicComponent } from "../isomorphic/component";
|
|
|
17
17
|
import { makePickComponentSync } from "../isomorphic/impl/make-pick-component-sync";
|
|
18
18
|
import { createQtStore } from "../store/create-store";
|
|
19
19
|
import { registerPageView, registerStoryShare, setMemberId, startAnalytics } from "./analytics";
|
|
20
|
-
import { initializeFCM } from "./impl/fcm";
|
|
21
20
|
import {
|
|
22
21
|
checkForServiceWorkerUpdates,
|
|
23
22
|
registerServiceWorker,
|
|
@@ -301,17 +300,6 @@ export function startApp(renderApplication, reducers, opts) {
|
|
|
301
300
|
|
|
302
301
|
store.dispatch({ type: NAVIGATE_TO_PAGE, page, currentPath: path });
|
|
303
302
|
|
|
304
|
-
// if (opts.firebaseConfig) {
|
|
305
|
-
// const fcm = typeof opts.firebaseConfig === "function" ? opts.firebaseConfig(page) : opts.firebaseConfig;
|
|
306
|
-
// if (fcm) {
|
|
307
|
-
// const mssgSenderId = fcm.messagingSenderId;
|
|
308
|
-
// const projectId = fcm.projectId;
|
|
309
|
-
// const apiKey = fcm.apiKey;
|
|
310
|
-
// console.log("fcm start app")
|
|
311
|
-
// if (mssgSenderId && projectId && apiKey) initializeFCM(fcm);
|
|
312
|
-
// }
|
|
313
|
-
// }
|
|
314
|
-
|
|
315
303
|
const { config: { "theme-attributes": pageThemeAttributes = {} } = {} } = page;
|
|
316
304
|
const version = pageThemeAttributes["cache-burst"] || app.getAppVersion();
|
|
317
305
|
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@ exports.registerFCMTopic = async function registerFCM (
|
|
|
5
5
|
req,
|
|
6
6
|
res,
|
|
7
7
|
next,
|
|
8
|
-
{ config, client, publisherConfig,
|
|
8
|
+
{ config, client, publisherConfig, fcmServiceCreds }
|
|
9
9
|
) {
|
|
10
10
|
console.log('fcm server')
|
|
11
11
|
const token = get(req, ['body', 'token'], null)
|
|
@@ -14,26 +14,17 @@ exports.registerFCMTopic = async function registerFCM (
|
|
|
14
14
|
return
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
const serviceAccount = typeof
|
|
18
|
-
console.log('fcmServerKey=====', serviceAccount)
|
|
19
|
-
console.log('client=', client)
|
|
20
|
-
console.log('admin.apps.length', admin.apps.length)
|
|
21
|
-
|
|
22
|
-
console.log('client=', client)
|
|
23
|
-
console.log('admin.apps.length', admin.apps.length)
|
|
17
|
+
const serviceAccount = typeof fcmServiceCreds === 'function' ? await fcmServiceCreds(config) : fcmServiceCreds
|
|
24
18
|
|
|
25
19
|
if (!admin.apps.length) {
|
|
26
20
|
admin.initializeApp({ credential: admin.credential.cert(serviceAccount) })
|
|
27
21
|
}
|
|
28
22
|
|
|
29
|
-
console.log('admin-----', admin)
|
|
30
23
|
try {
|
|
31
24
|
const data = await admin.messaging().subscribeToTopic(token, 'all')
|
|
32
|
-
console.log(`Successfully subscribed to topic----: ${data}`)
|
|
33
25
|
res.status(200).send(`Registration Done Successfully ${data}`)
|
|
34
26
|
return
|
|
35
27
|
} catch (error) {
|
|
36
|
-
console.error('Error subscribing to topic----:', error)
|
|
37
28
|
res.status(500).send(`FCM Subscription Failed: ${error}`)
|
|
38
29
|
return
|
|
39
30
|
}
|
package/server/routes.js
CHANGED
|
@@ -304,7 +304,7 @@ function getWithConfig (app, route, handler, opts = {}) {
|
|
|
304
304
|
* @param {boolean|function} shouldEncodeAmpUri If set to true, then for every story-page request the slug will be encoded, in case of a vernacular slug this should be set to false. Receives path as param (default: true)
|
|
305
305
|
* @param {number} sMaxAge Overrides the s-maxage value, the default value is set to 900 seconds. We can set `isomorphicRoutesSmaxage: 900` under `publisher` in publisher.yml config file that comes from BlackKnight or pass sMaxAge as a param.
|
|
306
306
|
* @param {number} maxAge Overrides the max-age value, the default value is set to 15 seconds. We can set `isomorphicRoutesMaxage: 15` under `publisher` in publisher.yml config file that comes from BlackKnight or pass maxAge as a param.
|
|
307
|
-
* @param {(
|
|
307
|
+
* @param {(object|function)} fcmServiceCreds FCM service creds is used for registering FCM Topic.
|
|
308
308
|
* @param {string} appLoadingPlaceholder This string gets injected into the app container when the page is loaded via service worker. Can be used to show skeleton layouts, animations or other progress indicators before it is replaced by the page content.
|
|
309
309
|
* @param {boolean|function} enableExternalStories If set to true, then for every request an external story api call is made and renders the story-page if the story is found. (default: false)
|
|
310
310
|
* @param {string|function} externalIdPattern This string specifies the external id pattern the in the url. Mention `EXTERNAL_ID` to specify the position of external id in the url. Ex: "/parent-section/child-section/EXTERNAL_ID"
|
|
@@ -352,7 +352,7 @@ exports.isomorphicRoutes = function isomorphicRoutes (
|
|
|
352
352
|
sMaxAge = 900,
|
|
353
353
|
maxAge = 15,
|
|
354
354
|
appLoadingPlaceholder = '',
|
|
355
|
-
|
|
355
|
+
fcmServiceCreds = {},
|
|
356
356
|
webengageConfig = {},
|
|
357
357
|
externalIdPattern = '',
|
|
358
358
|
enableExternalStories = false,
|
|
@@ -469,7 +469,7 @@ exports.isomorphicRoutes = function isomorphicRoutes (
|
|
|
469
469
|
})
|
|
470
470
|
)
|
|
471
471
|
|
|
472
|
-
app.post('/register-fcm-topic', bodyParser.json(), withConfig(registerFCMTopic, { publisherConfig,
|
|
472
|
+
app.post('/register-fcm-topic', bodyParser.json(), withConfig(registerFCMTopic, { publisherConfig, fcmServiceCreds }))
|
|
473
473
|
|
|
474
474
|
if (webengageConfig.enableWebengage) {
|
|
475
475
|
app.post(
|
|
@@ -7,355 +7,355 @@ const supertest = require("supertest");
|
|
|
7
7
|
describe("Sketches Proxy", function () {
|
|
8
8
|
let upstreamServer;
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
10
|
+
before(function (next) {
|
|
11
|
+
const upstreamApp = express();
|
|
12
|
+
upstreamApp.all("/*", (req, res) =>
|
|
13
|
+
res.send(
|
|
14
|
+
JSON.stringify({
|
|
15
|
+
method: req.method,
|
|
16
|
+
url: req.url,
|
|
17
|
+
host: req.headers.host,
|
|
18
|
+
})
|
|
19
|
+
)
|
|
20
|
+
);
|
|
21
|
+
upstreamServer = upstreamApp.listen(next);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe("forwarding requests", function () {
|
|
25
|
+
function buildApp({ app = express() } = {}) {
|
|
26
|
+
upstreamQuintypeRoutes(app, {
|
|
27
|
+
config: {
|
|
28
|
+
sketches_host: `http://127.0.0.1:${upstreamServer.address().port}`,
|
|
29
|
+
},
|
|
30
|
+
getClient: (host) => ({ getHostname: () => host.toUpperCase() }),
|
|
31
|
+
extraRoutes: ["/custom-route"],
|
|
32
|
+
forwardAmp: true,
|
|
33
|
+
forwardFavicon: true,
|
|
34
|
+
publisherConfig: {},
|
|
35
|
+
});
|
|
36
|
+
return app;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
it("forwards requests to sketches", function (done) {
|
|
40
|
+
supertest(buildApp())
|
|
41
|
+
.get("/api/v1/config")
|
|
42
|
+
.expect(200)
|
|
43
|
+
.then((res) => {
|
|
44
|
+
const { method, url, host } = JSON.parse(res.text);
|
|
45
|
+
assert.equal("GET", method);
|
|
46
|
+
assert.equal("/api/v1/config", url);
|
|
47
|
+
assert.equal("127.0.0.1", host);
|
|
48
|
+
})
|
|
49
|
+
.then(done);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("forwards subdirectory api requests to sketches", function (done) {
|
|
53
|
+
supertest(buildApp())
|
|
54
|
+
.get("/anything/api/v1/config")
|
|
55
|
+
.expect(200)
|
|
56
|
+
.then((res) => {
|
|
57
|
+
const { method, url, host } = JSON.parse(res.text);
|
|
58
|
+
assert.equal("GET", method);
|
|
59
|
+
assert.equal("/anything/api/v1/config", url);
|
|
60
|
+
assert.equal("127.0.0.1", host);
|
|
61
|
+
})
|
|
62
|
+
.then(done);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("forwards custom routes to sketches", function (done) {
|
|
66
|
+
supertest(buildApp())
|
|
67
|
+
.get("/custom-route")
|
|
68
|
+
.expect(200)
|
|
69
|
+
.then((res) => {
|
|
70
|
+
const { method, url, host } = JSON.parse(res.text);
|
|
71
|
+
assert.equal("GET", method);
|
|
72
|
+
assert.equal("/custom-route", url);
|
|
73
|
+
assert.equal("127.0.0.1", host);
|
|
74
|
+
})
|
|
75
|
+
.then(done);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("grabs the hostname from the client", function (done) {
|
|
79
|
+
supertest(buildApp())
|
|
80
|
+
.get("/amp/story/foo")
|
|
81
|
+
.set("Host", "foobar.com")
|
|
82
|
+
.expect(200)
|
|
83
|
+
.then((res) => {
|
|
84
|
+
const { host } = JSON.parse(res.text);
|
|
85
|
+
assert.equal("FOOBAR.COM", host);
|
|
86
|
+
})
|
|
87
|
+
.then(done);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("does not forward unknown requests", function (done) {
|
|
91
|
+
supertest(buildApp()).get("/unknown").expect(404, done);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("forwards amp requests", function (done) {
|
|
95
|
+
supertest(buildApp())
|
|
96
|
+
.get("/amp/story/foo")
|
|
97
|
+
.expect(200)
|
|
98
|
+
.then((res) => {
|
|
99
|
+
const { url } = JSON.parse(res.text);
|
|
100
|
+
assert.equal("/amp/story/foo", url);
|
|
101
|
+
})
|
|
102
|
+
.then(done);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("gets favicon", function (done) {
|
|
106
|
+
supertest(buildApp())
|
|
107
|
+
.get("/favicon.ico")
|
|
108
|
+
.expect(200)
|
|
109
|
+
.then((res) => {
|
|
110
|
+
const { url } = JSON.parse(res.text);
|
|
111
|
+
assert.equal("/favicon.ico", url);
|
|
112
|
+
})
|
|
113
|
+
.then(done);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("allows mounting at a different path", function (done) {
|
|
117
|
+
const app = express();
|
|
118
|
+
mountQuintypeAt(app, "/foo");
|
|
119
|
+
supertest(buildApp({ app }))
|
|
120
|
+
.get("/foo/api/v1/config")
|
|
121
|
+
.expect(200)
|
|
122
|
+
.then((res) => {
|
|
123
|
+
const { method, url, host } = JSON.parse(res.text);
|
|
124
|
+
assert.equal("GET", method);
|
|
125
|
+
assert.equal("/api/v1/config", url);
|
|
126
|
+
assert.equal("127.0.0.1", host);
|
|
127
|
+
})
|
|
128
|
+
.then(done);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe("Override the s-maxage cache header", function () {
|
|
133
|
+
function getClientStub(hostname) {
|
|
134
|
+
return {
|
|
135
|
+
getHostname: () => "demo.quintype.io",
|
|
136
|
+
getConfig: () =>
|
|
137
|
+
Promise.resolve({
|
|
138
|
+
foo: "bar",
|
|
139
|
+
"sketches-host": "https://www.foo.com",
|
|
140
|
+
}),
|
|
141
|
+
baseUrl: "https://www.foo.com",
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function buildApp(sMaxAge, { app = express() } = {}) {
|
|
145
|
+
upstreamQuintypeRoutes(app, {
|
|
146
|
+
config: {
|
|
147
|
+
sketches_host: `https://demo.quintype.io`,
|
|
148
|
+
},
|
|
149
|
+
getClient: getClientStub,
|
|
150
|
+
extraRoutes: ["/custom-route"],
|
|
151
|
+
forwardAmp: true,
|
|
152
|
+
forwardFavicon: true,
|
|
153
|
+
publisherConfig: {},
|
|
154
|
+
sMaxAge: sMaxAge,
|
|
155
|
+
});
|
|
156
|
+
return app;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
it("Override the s-maxage cache header when sMaxAge value is present", function (done) {
|
|
160
|
+
const sMaxAge = 900;
|
|
161
|
+
supertest(buildApp(sMaxAge))
|
|
162
|
+
.get("/api/v1/config")
|
|
163
|
+
.expect(200)
|
|
164
|
+
.then((res) => {
|
|
165
|
+
const cacheControl = res.headers["cache-control"];
|
|
166
|
+
assert.equal(cacheControl, "public,max-age=15,s-maxage=900,stale-while-revalidate=300,stale-if-error=7200");
|
|
167
|
+
})
|
|
168
|
+
.then(done);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it("Does not override the s-maxage cache header if cacheability is Private", function (done) {
|
|
172
|
+
const sMaxAge = 900;
|
|
173
|
+
supertest(buildApp(sMaxAge))
|
|
174
|
+
.get("/api/auth/v1/users/me")
|
|
175
|
+
.then((res) => {
|
|
176
|
+
const cacheControl = res.headers["cache-control"];
|
|
177
|
+
assert.equal(cacheControl, "private,no-cache,no-store");
|
|
178
|
+
})
|
|
179
|
+
.then(done);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it("Does not override the s-maxage cache header for Breaking News", function (done) {
|
|
183
|
+
const sMaxAge = 900;
|
|
184
|
+
supertest(buildApp(sMaxAge))
|
|
185
|
+
.get("/api/v1/breaking-news")
|
|
186
|
+
.then((res) => {
|
|
187
|
+
const cacheControl = res.headers["cache-control"];
|
|
188
|
+
assert.equal(cacheControl, "public,max-age=15,s-maxage=240,stale-while-revalidate=300,stale-if-error=7200");
|
|
189
|
+
})
|
|
190
|
+
.then(done);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it("if sMaxAge value is not present, do not override cache headers", function (done) {
|
|
194
|
+
supertest(buildApp())
|
|
195
|
+
.get("/api/v1/config")
|
|
196
|
+
.expect(200)
|
|
197
|
+
.then((res) => {
|
|
198
|
+
const cacheControl = res.headers["cache-control"];
|
|
199
|
+
assert.equal(cacheControl, "public,max-age=15,s-maxage=240,stale-while-revalidate=300,stale-if-error=7200");
|
|
200
|
+
})
|
|
201
|
+
.then(done);
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
describe("Override the max-age cache header", function () {
|
|
206
|
+
function getClientStub(hostname) {
|
|
207
|
+
return {
|
|
208
|
+
getHostname: () => "demo.quintype.io",
|
|
209
|
+
getConfig: () =>
|
|
210
|
+
Promise.resolve({
|
|
211
|
+
foo: "bar",
|
|
212
|
+
"sketches-host": "https://www.foo.com",
|
|
213
|
+
}),
|
|
214
|
+
baseUrl: "https://www.foo.com",
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function buildApp(maxAge, { app = express() } = {}) {
|
|
218
|
+
upstreamQuintypeRoutes(app, {
|
|
219
|
+
config: {
|
|
220
|
+
sketches_host: `https://demo.quintype.io`,
|
|
221
|
+
},
|
|
222
|
+
getClient: getClientStub,
|
|
223
|
+
extraRoutes: ["/custom-route"],
|
|
224
|
+
forwardAmp: true,
|
|
225
|
+
forwardFavicon: true,
|
|
226
|
+
publisherConfig: {},
|
|
227
|
+
maxAge: maxAge,
|
|
228
|
+
});
|
|
229
|
+
return app;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
it("Override the max-age cache header when maxAge value is present", function (done) {
|
|
233
|
+
const maxAge = 3600;
|
|
234
|
+
supertest(buildApp(maxAge))
|
|
235
|
+
.get("/api/v1/config")
|
|
236
|
+
.expect(200)
|
|
237
|
+
.then((res) => {
|
|
238
|
+
const cacheControl = res.headers["cache-control"];
|
|
239
|
+
assert.equal(cacheControl, "public,max-age=3600,s-maxage=240,stale-while-revalidate=300,stale-if-error=7200");
|
|
240
|
+
})
|
|
241
|
+
.then(done);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it("Does not override the max-age cache header if cacheability is Private", function (done) {
|
|
245
|
+
const maxAge = 15;
|
|
246
|
+
supertest(buildApp(maxAge))
|
|
247
|
+
.get("/api/auth/v1/users/me")
|
|
248
|
+
.then((res) => {
|
|
249
|
+
const cacheControl = res.headers["cache-control"];
|
|
250
|
+
assert.equal(cacheControl, "private,no-cache,no-store");
|
|
251
|
+
})
|
|
252
|
+
.then(done);
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it("Does not override the max-age cache header for Breaking News", function (done) {
|
|
256
|
+
const maxAge = 3600;
|
|
257
|
+
supertest(buildApp(maxAge))
|
|
258
|
+
.get("/api/v1/breaking-news")
|
|
259
|
+
.then((res) => {
|
|
260
|
+
const cacheControl = res.headers["cache-control"];
|
|
261
|
+
assert.equal(cacheControl, "public,max-age=15,s-maxage=240,stale-while-revalidate=300,stale-if-error=7200");
|
|
262
|
+
})
|
|
263
|
+
.then(done);
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it("if maxAge value is not present, do not override cache headers", function (done) {
|
|
267
|
+
supertest(buildApp())
|
|
268
|
+
.get("/api/v1/config")
|
|
269
|
+
.expect(200)
|
|
270
|
+
.then((res) => {
|
|
271
|
+
const cacheControl = res.headers["cache-control"];
|
|
272
|
+
assert.equal(cacheControl, "public,max-age=15,s-maxage=240,stale-while-revalidate=300,stale-if-error=7200");
|
|
273
|
+
})
|
|
274
|
+
.then(done);
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
describe("sitemap requests", function () {
|
|
279
|
+
function buildApp({ isSitemapUrlEnabled }) {
|
|
280
|
+
const app = express();
|
|
281
|
+
upstreamQuintypeRoutes(app, {
|
|
282
|
+
config: {
|
|
283
|
+
sketches_host: `http://127.0.0.1:${upstreamServer.address().port}`,
|
|
284
|
+
},
|
|
285
|
+
getClient: (host) => ({ getHostname: () => host.toUpperCase() }),
|
|
286
|
+
extraRoutes: ["/custom-route"],
|
|
287
|
+
publisherConfig: {},
|
|
288
|
+
isSitemapUrlEnabled,
|
|
289
|
+
});
|
|
290
|
+
return app;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
it("forwards requests to test new_sitemap/today.xml should not throw error if isSitemapUrlEnabled is enabled", function (done) {
|
|
294
|
+
supertest(buildApp({ isSitemapUrlEnabled: true }))
|
|
295
|
+
.get("/news_sitemap/today.xml")
|
|
296
|
+
.set("Host", "foobar.com")
|
|
297
|
+
.expect(200)
|
|
298
|
+
.then((res) => {
|
|
299
|
+
const { host } = JSON.parse(res.text);
|
|
300
|
+
assert.equal("FOOBAR.COM", host);
|
|
301
|
+
})
|
|
302
|
+
.then(done);
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it("forwards requests to test news_sitemap.xml should not throw error if isSitemapUrlEnabled is disabled", function (done) {
|
|
306
|
+
supertest(buildApp({ isSitemapUrlEnabled: false }))
|
|
307
|
+
.get("/news_sitemap.xml")
|
|
308
|
+
.set("Host", "foobar.com")
|
|
309
|
+
.expect(200)
|
|
310
|
+
.then((res) => {
|
|
311
|
+
const { host } = JSON.parse(res.text);
|
|
312
|
+
assert.equal("FOOBAR.COM", host);
|
|
313
|
+
})
|
|
314
|
+
.then(done);
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
describe("ping check", function () {
|
|
319
|
+
function buildApp(getConfig) {
|
|
320
|
+
const app = express();
|
|
321
|
+
upstreamQuintypeRoutes(app, {
|
|
322
|
+
config: {
|
|
323
|
+
sketches_host: `http://127.0.0.1:${upstreamServer.address().port}`,
|
|
324
|
+
},
|
|
325
|
+
getClient: (host) => ({ getConfig }),
|
|
326
|
+
});
|
|
327
|
+
return app;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
it("returns a successful ping if the config is loaded", async function () {
|
|
331
|
+
await supertest(buildApp(() => Promise.resolve({})))
|
|
332
|
+
.get("/ping")
|
|
333
|
+
.expect(200);
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
it("fails with a 503 if the config fails", async function () {
|
|
337
|
+
await supertest(buildApp(() => Promise.reject({})))
|
|
338
|
+
.get("/ping")
|
|
339
|
+
.expect(503);
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
it("responds with a ping even if it's mounted somewhere", async function () {
|
|
343
|
+
const app = express();
|
|
344
|
+
mountQuintypeAt(app, "/foo");
|
|
345
|
+
upstreamQuintypeRoutes(app, {
|
|
346
|
+
config: {
|
|
347
|
+
sketches_host: `http://127.0.0.1:${upstreamServer.address().port}`,
|
|
348
|
+
},
|
|
349
|
+
getClient: (host) => ({ getConfig: () => Promise.resolve({}) }),
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
await supertest(app).get("/ping").expect(200);
|
|
353
|
+
|
|
354
|
+
await supertest(app).get("/foo/ping").expect(200);
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
after(function () {
|
|
359
|
+
upstreamServer.close();
|
|
360
|
+
});
|
|
361
361
|
});
|
package/client/impl/fcm.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
export function initializeFCM (firebaseConfig) {
|
|
2
|
-
Promise.all([
|
|
3
|
-
import(/* webpackChunkName: "firebase-app" */ 'firebase/app'),
|
|
4
|
-
import(/* webpackChunkName: "firebase-messaging" */ 'firebase/messaging')
|
|
5
|
-
])
|
|
6
|
-
.then(async ([firebase, m]) => {
|
|
7
|
-
console.log('firebaseConfig=====', firebaseConfig)
|
|
8
|
-
const app = firebase.initializeApp({
|
|
9
|
-
messagingSenderId: firebaseConfig.messagingSenderId.toString(),
|
|
10
|
-
projectId: firebaseConfig.projectId,
|
|
11
|
-
apiKey: firebaseConfig.apiKey,
|
|
12
|
-
storageBucket: firebaseConfig.storageBucket,
|
|
13
|
-
authDomain: firebaseConfig.authDomain,
|
|
14
|
-
appId: firebaseConfig.appId
|
|
15
|
-
})
|
|
16
|
-
const messaging = m.getMessaging(app)
|
|
17
|
-
await requestPermission(m, firebaseConfig, messaging)
|
|
18
|
-
m.onMessage(messaging, ({ notification }) => {
|
|
19
|
-
console.log('notificaation----- client', notification)
|
|
20
|
-
new Notification(notification.title, {
|
|
21
|
-
body: notification.body,
|
|
22
|
-
icon: notification.icon
|
|
23
|
-
})
|
|
24
|
-
})
|
|
25
|
-
})
|
|
26
|
-
.catch(err => {
|
|
27
|
-
console.error(`FCM subscription failed ${err}`)
|
|
28
|
-
})
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async function requestPermission (m, firebaseConfig, messaging) {
|
|
32
|
-
const permission = await Notification.requestPermission()
|
|
33
|
-
console.log('permission------', permission)
|
|
34
|
-
if (permission === 'granted') {
|
|
35
|
-
const token = m.getToken(messaging, {
|
|
36
|
-
vapidKey: firebaseConfig.vapidKey
|
|
37
|
-
})
|
|
38
|
-
return registerFCMTopic(token)
|
|
39
|
-
} else if (permission === 'denied') {
|
|
40
|
-
console.log('notifications are denied')
|
|
41
|
-
return
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function registerFCMTopic (token) {
|
|
46
|
-
return fetch('/register-fcm-topic', {
|
|
47
|
-
method: 'post',
|
|
48
|
-
headers: {
|
|
49
|
-
'Content-Type': 'application/json'
|
|
50
|
-
},
|
|
51
|
-
body: JSON.stringify({ token: token })
|
|
52
|
-
})
|
|
53
|
-
}
|