-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathserver.js
More file actions
122 lines (96 loc) · 2.92 KB
/
server.js
File metadata and controls
122 lines (96 loc) · 2.92 KB
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
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
const express = require('express');
const http = require('http');
const Hub = require('./hub');
const Publisher = require('./publisher');
const { getAuthorizedTargets } = require('./authorization');
function publishEndpointHandler() {
return async (req, res, next) => {
const hub = req.app.get('hub');
// Authorize publisher
let claims;
try {
claims = await hub.authorizePublish(req);
} catch (err) {
return res.status(401).send('Unauthorized');
}
if (!claims) {
return res.status(403).send('Forbidden');
}
const { topic, data, target: targets, id, type } = req.body;
let { retry } = req.body;
if (!topic || topic === '') {
return res.status(400).send('Missing "topic" parameter in body');
}
if (!data || data === '') {
return res.status(400).send('Missing "data" parameter in body');
}
if (hub.config.maxTopics > 0 && topics.length > hub.config.maxTopics) {
return res.status(400).send(`Exceeded limit of ${hub.config.maxTopics} topics`);
}
if (retry) {
retry = parseInt(retry, 10) || 0;
if (!Number.isInteger(retry)) {
return res.status(400).send('Invalid "retry" parameter');
}
}
const { allTargetsAuthorized, authorizedTargets } = getAuthorizedTargets(claims, true);
const targetsArray = Array.isArray(targets) ? targets : [targets];
// Checking if all targets are authorized.
for (const target of targetsArray) {
if (!allTargetsAuthorized) {
if (!authorizedTargets.includes(target)) {
return res.status(401).send('Unauthorized');
}
}
}
const publisher = new Publisher(hub);
try {
const updateId = await publisher.publish(topic, data, {
allTargets: allTargetsAuthorized,
targets,
...id ? { id } : {},
...type ? { type } : {},
...retry ? { retry } : {},
});
return res.status(200).send(updateId);
} catch (err) {
return next(err);
}
};
}
/**
* Mercure server built on Express.
*/
class Server {
constructor(config = {}) {
this.config = {
path: '/.well-known/mercure',
...config
};
this.app = express();
if (typeof this.configure === 'function') {
this.configure.call(this);
}
this.app.use(express.urlencoded({ extended: true }));
const { server, hub } = Server.createFromExpressApp(this.app, this.config);
this.server = server;
this.hub = hub;
}
static createFromExpressApp(app, config) {
app.post('/.well-known/mercure', publishEndpointHandler());
const server = http.Server(app);
const hub = new Hub(server, config);
app.set('hub', hub);
return { server, hub };
}
async listen(port, addr = null) {
await this.hub.listen(port, addr);
}
async end({ force = false } = {}) {
await this.hub.end({ force });
}
endSync() {
return this.hub.endSync();
}
}
module.exports = Server;