add basic token creation and message sending
This commit is contained in:
parent
b39f22deb5
commit
3dd2e6ada1
9 changed files with 407 additions and 3 deletions
80
WatchedGuild.js
Normal file
80
WatchedGuild.js
Normal file
|
@ -0,0 +1,80 @@
|
|||
const { EventEmitter } = require("events");
|
||||
|
||||
class WatchedGuild extends EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.knownWebhooks = new Map();
|
||||
this.eventStack = [];
|
||||
this.upstreamGuildId = null;
|
||||
}
|
||||
|
||||
pushEvent(e) {
|
||||
this.eventStack.push(e);
|
||||
this.emit("pushed", e);
|
||||
}
|
||||
|
||||
consumeEvent() {
|
||||
return this.eventStack.pop();
|
||||
}
|
||||
|
||||
consumeAll() {
|
||||
const events = [...this.eventStack];
|
||||
this.eventStack = [];
|
||||
return events;
|
||||
}
|
||||
|
||||
hasEvents() {
|
||||
return this.eventStack.length > 0;
|
||||
}
|
||||
|
||||
_pushMessageEvent(message) {
|
||||
this.pushEvent({
|
||||
eventType: "messageCreate",
|
||||
message: message.toJSON()
|
||||
});
|
||||
}
|
||||
|
||||
discordConnect(bot) {
|
||||
this.bot = bot;
|
||||
this.bot.on("messageCreate", (message) => {
|
||||
if (message.guildId !== this.upstreamGuildId)
|
||||
return;
|
||||
|
||||
this._pushMessageEvent(message);
|
||||
});
|
||||
}
|
||||
|
||||
async discordSendMessage(messageContent, channelId, username, avatarURL=undefined) {
|
||||
if (!this.bot)
|
||||
throw new Error("Bot not connected");
|
||||
|
||||
let webhook = this.knownWebhooks.get(channelId);
|
||||
if (!webhook) {
|
||||
webhook = (await this.bot.getChannelWebhooks(channelId))
|
||||
.filter(w => w.name == "well_known__bridge")[0];
|
||||
|
||||
if (!webhook)
|
||||
webhook = await this.bot.createChannelWebhook(channelId, {
|
||||
name: "well_known__bridge"
|
||||
}, "This webhook was created by the bridge API bot.");
|
||||
|
||||
this.knownWebhooks.set(channelId, webhook);
|
||||
}
|
||||
|
||||
await this.bot.executeWebhook(webhook.id, webhook.token, {
|
||||
allowedMentions: {
|
||||
everyone: false,
|
||||
roles: false,
|
||||
users: true
|
||||
},
|
||||
content: messageContent,
|
||||
tts: false,
|
||||
wait: true,
|
||||
avatarURL,
|
||||
username
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = WatchedGuild;
|
28
common.js
Normal file
28
common.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
const Eris = require("eris");
|
||||
const { discordToken, watchedGuildIds } = require("./config");
|
||||
const WatchedGuild = require("./WatchedGuild");
|
||||
|
||||
const bot = new Eris(discordToken, {
|
||||
intents: [
|
||||
"guildMessages"
|
||||
]
|
||||
});
|
||||
|
||||
const guildMap = new Map();
|
||||
|
||||
bot.on("ready", () => {
|
||||
console.log("discord bot: ready");
|
||||
watchedGuildIds.forEach(id => {
|
||||
const watchedGuild = new WatchedGuild();
|
||||
watchedGuild.upstreamGuildId = id;
|
||||
watchedGuild.discordConnect(bot);
|
||||
guildMap.set(id, watchedGuild);
|
||||
});
|
||||
});
|
||||
|
||||
bot.connect();
|
||||
|
||||
module.exports = {
|
||||
bot,
|
||||
guildMap
|
||||
};
|
7
config.js
Normal file
7
config.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
module.exports = {
|
||||
mainHttpListenPort: 4050,
|
||||
watchedGuildIds: ["822089558886842418"],
|
||||
jwtSecret: process.env.JWT_SECRET,
|
||||
discordToken: process.env.DISCORD_TOKEN,
|
||||
dangerousAdminMode: true
|
||||
};
|
16
index.js
16
index.js
|
@ -0,0 +1,16 @@
|
|||
const express = require("express");
|
||||
const { mainHttpListenPort } = require("./config");
|
||||
const app = express();
|
||||
const apiRoute = require("./routes/api");
|
||||
|
||||
app.use(express.json());
|
||||
app.use("/", express.static("public/"));
|
||||
app.use("/api/v1", apiRoute);
|
||||
|
||||
app.get("/", (req, res) => {
|
||||
res.send("hello");
|
||||
});
|
||||
|
||||
app.listen(mainHttpListenPort, () => {
|
||||
console.log(`server main: listen on ${mainHttpListenPort}`);
|
||||
});
|
|
@ -4,6 +4,8 @@
|
|||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"express": "^4.17.2"
|
||||
"eris": "^0.16.1",
|
||||
"express": "^4.17.2",
|
||||
"jsonwebtoken": "^8.5.1"
|
||||
}
|
||||
}
|
||||
|
|
49
public/index.html
Normal file
49
public/index.html
Normal file
|
@ -0,0 +1,49 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<button onclick="createToken('testinguser', '0', ['0']);">create token</button>
|
||||
<button onclick="sendMessage('0', '0', 'hello');">send message</button>
|
||||
|
||||
<script>
|
||||
let createdToken;
|
||||
|
||||
async function createToken(username, discordID, guildAccess) {
|
||||
const res = await fetch("http://localhost:4050/api/v1/tokens/create", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
username,
|
||||
discordID,
|
||||
guildAccess
|
||||
}),
|
||||
headers: {
|
||||
"content-type": "application/json"
|
||||
}
|
||||
});
|
||||
const json = await res.json();
|
||||
console.log("createToken()", json);
|
||||
createdToken = json.token;
|
||||
}
|
||||
|
||||
async function sendMessage(guildId, channelId, content) {
|
||||
const res = await fetch(`http://localhost:4050/api/v1/guilds/${guildId}/channels/${channelId}/messages/create`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
content
|
||||
}),
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
"authorization": createdToken
|
||||
}
|
||||
});
|
||||
const json = await res.json();
|
||||
console.log("sendMessage()", json);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
56
routes/api.js
Normal file
56
routes/api.js
Normal file
|
@ -0,0 +1,56 @@
|
|||
const express = require("express");
|
||||
const { guildMap } = require("../common");
|
||||
const { dangerousAdminMode } = require("../config");
|
||||
const { checkAuth, createToken } = require("../tokens");
|
||||
const router = express();
|
||||
|
||||
router.get("/", (req, res) => {
|
||||
res.status(200).send({ error: false, message: "SUCCESS_API_OK" });
|
||||
});
|
||||
|
||||
router.post("/tokens/create", async (req, res) => {
|
||||
if (!dangerousAdminMode)
|
||||
return res.status(403).send({ error: true, message: "ERROR_FEATURE_DISABLED" });
|
||||
|
||||
const { username, avatarURL, discordID, guildAccess } = req.body;
|
||||
if (!username || !discordID || !guildAccess)
|
||||
return res.status(400).send({ error: true, message: "ERROR_BAD_REQUEST" });
|
||||
|
||||
try {
|
||||
const token = await createToken({ username, avatarURL, discordID, guildAccess });
|
||||
res.status(200).send({ error: false, message: "SUCCESS_TOKEN_CREATED", token });
|
||||
} catch(e) {
|
||||
res.status(500).send({ error: true, message: "ERROR_TOKEN_CREATE_FAILURE" });
|
||||
}
|
||||
});
|
||||
|
||||
router.post("/guilds/:guildId/channels/:channelId/messages/create", checkAuth(async (req, res) => {
|
||||
const messageContent = req.body.content;
|
||||
if (!messageContent)
|
||||
return res.status(400).send({ error: true, message: "ERROR_NO_MESSAGE_CONTENT" });
|
||||
|
||||
const guildId = req.params.guildId;
|
||||
if (!guildId)
|
||||
return res.status(400).send({ error: true, message: "ERROR_NO_GUILD_ID" });
|
||||
|
||||
const channelId = req.params.channelId;
|
||||
if (!channelId)
|
||||
return res.status(400).send({ error: true, message: "ERROR_NO_CHANNEL_ID" });
|
||||
|
||||
|
||||
const { username, avatarURL, guildAccess } = req.user;
|
||||
|
||||
if (guildAccess.indexOf(guildId) === -1)
|
||||
return res.status(403).send({ error: true, message: "ERROR_NO_GUILD_ACCESS" });
|
||||
|
||||
const guild = guildMap.get(guildId);
|
||||
try {
|
||||
await guild.discordSendMessage(messageContent, channelId, username, avatarURL);
|
||||
res.status(201).send({ error: false, message: "SUCCESS_MESSAGE_CREATED" });
|
||||
} catch(e) {
|
||||
console.error("server main: api: message create: error: ", e);
|
||||
res.status(500).send({ error: true, message: "ERROR_MESSAGE_SEND_FAILURE" });
|
||||
}
|
||||
}));
|
||||
|
||||
module.exports = router;
|
56
tokens.js
Normal file
56
tokens.js
Normal file
|
@ -0,0 +1,56 @@
|
|||
const jsonwebtoken = require("jsonwebtoken");
|
||||
const { jwtSecret } = require("./config");
|
||||
|
||||
function createToken({ username, avatarURL, discordID, guildAccess }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
jsonwebtoken.sign({ username, avatarURL, discordID, guildAccess }, jwtSecret, (err, token) => {
|
||||
if (err)
|
||||
return reject(err);
|
||||
|
||||
resolve(token);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function decodeToken(token) {
|
||||
return new Promise((resolve, reject) => {
|
||||
jsonwebtoken.verify(token, jwtSecret, (err, token) => {
|
||||
if (err)
|
||||
return reject(err);
|
||||
|
||||
resolve(token);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function checkAuth(callback) {
|
||||
return async (req, res) => {
|
||||
const token = req.get("authorization");
|
||||
if (token) {
|
||||
let user;
|
||||
try {
|
||||
user = await decodeToken(token);
|
||||
} catch(e) {
|
||||
res.status(403).send({ error: true, message: "ERROR_FORBIDDEN" });
|
||||
return;
|
||||
}
|
||||
if (user) {
|
||||
req.user = user;
|
||||
req.authenticated = true;
|
||||
return await callback(req, res);
|
||||
} else {
|
||||
res.status(401).send({ error: true, message: "ERROR_UNAUTHORIZED" });
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
res.status(401).send({ error: true, message: "ERROR_UNAUTHORIZED" });
|
||||
return;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createToken,
|
||||
decodeToken,
|
||||
checkAuth
|
||||
};
|
114
yarn.lock
114
yarn.lock
|
@ -31,6 +31,11 @@ body-parser@1.19.1:
|
|||
raw-body "2.4.2"
|
||||
type-is "~1.6.18"
|
||||
|
||||
buffer-equal-constant-time@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
|
||||
integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
|
||||
|
||||
bytes@3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a"
|
||||
|
@ -75,6 +80,13 @@ destroy@~1.0.4:
|
|||
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
|
||||
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
|
||||
|
||||
ecdsa-sig-formatter@1.0.11:
|
||||
version "1.0.11"
|
||||
resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
|
||||
integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
|
||||
dependencies:
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
ee-first@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
||||
|
@ -85,6 +97,16 @@ encodeurl@~1.0.2:
|
|||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
||||
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
|
||||
|
||||
eris@^0.16.1:
|
||||
version "0.16.1"
|
||||
resolved "https://registry.yarnpkg.com/eris/-/eris-0.16.1.tgz#44b0a9220944fc73dd74538cd614826bfbfcde61"
|
||||
integrity sha512-fqjgaddSvUlUjA7s85OvZimLrgCwX58Z6FXOIxdNFJdT6XReJ/LOWZKdew2CaalM8BvN2JKzn98HmKYb3zMhKg==
|
||||
dependencies:
|
||||
ws "^8.2.3"
|
||||
optionalDependencies:
|
||||
opusscript "^0.0.8"
|
||||
tweetnacl "^1.0.3"
|
||||
|
||||
escape-html@~1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
|
||||
|
@ -182,6 +204,74 @@ ipaddr.js@1.9.1:
|
|||
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
|
||||
integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
|
||||
|
||||
jsonwebtoken@^8.5.1:
|
||||
version "8.5.1"
|
||||
resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
|
||||
integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==
|
||||
dependencies:
|
||||
jws "^3.2.2"
|
||||
lodash.includes "^4.3.0"
|
||||
lodash.isboolean "^3.0.3"
|
||||
lodash.isinteger "^4.0.4"
|
||||
lodash.isnumber "^3.0.3"
|
||||
lodash.isplainobject "^4.0.6"
|
||||
lodash.isstring "^4.0.1"
|
||||
lodash.once "^4.0.0"
|
||||
ms "^2.1.1"
|
||||
semver "^5.6.0"
|
||||
|
||||
jwa@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a"
|
||||
integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==
|
||||
dependencies:
|
||||
buffer-equal-constant-time "1.0.1"
|
||||
ecdsa-sig-formatter "1.0.11"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
jws@^3.2.2:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
|
||||
integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
|
||||
dependencies:
|
||||
jwa "^1.4.1"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
lodash.includes@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
|
||||
integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=
|
||||
|
||||
lodash.isboolean@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
|
||||
integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
|
||||
|
||||
lodash.isinteger@^4.0.4:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
|
||||
integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=
|
||||
|
||||
lodash.isnumber@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
|
||||
integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=
|
||||
|
||||
lodash.isplainobject@^4.0.6:
|
||||
version "4.0.6"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
|
||||
integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
|
||||
|
||||
lodash.isstring@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
|
||||
integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
|
||||
|
||||
lodash.once@^4.0.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
||||
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
|
||||
|
||||
media-typer@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
|
@ -219,7 +309,7 @@ ms@2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||
|
||||
ms@2.1.3:
|
||||
ms@2.1.3, ms@^2.1.1:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||
|
@ -236,6 +326,11 @@ on-finished@~2.3.0:
|
|||
dependencies:
|
||||
ee-first "1.1.1"
|
||||
|
||||
opusscript@^0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/opusscript/-/opusscript-0.0.8.tgz#00b49e81281b4d99092d013b1812af8654bd0a87"
|
||||
integrity sha512-VSTi1aWFuCkRCVq+tx/BQ5q9fMnQ9pVZ3JU4UHKqTkf0ED3fKEPdr+gKAAl3IA2hj9rrP6iyq3hlcJq3HELtNQ==
|
||||
|
||||
parseurl@~1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
|
||||
|
@ -274,7 +369,7 @@ raw-body@2.4.2:
|
|||
iconv-lite "0.4.24"
|
||||
unpipe "1.0.0"
|
||||
|
||||
safe-buffer@5.2.1:
|
||||
safe-buffer@5.2.1, safe-buffer@^5.0.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
@ -284,6 +379,11 @@ safe-buffer@5.2.1:
|
|||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
semver@^5.6.0:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||
|
||||
send@0.17.2:
|
||||
version "0.17.2"
|
||||
resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820"
|
||||
|
@ -328,6 +428,11 @@ toidentifier@1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
|
||||
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
|
||||
|
||||
tweetnacl@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596"
|
||||
integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==
|
||||
|
||||
type-is@~1.6.18:
|
||||
version "1.6.18"
|
||||
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
|
||||
|
@ -350,3 +455,8 @@ vary@~1.1.2:
|
|||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
|
||||
|
||||
ws@^8.2.3:
|
||||
version "8.4.2"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.4.2.tgz#18e749868d8439f2268368829042894b6907aa0b"
|
||||
integrity sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==
|
||||
|
|
Loading…
Reference in a new issue