Add ape keys routing and configuration (#2599)

* Add ape keys routing and configuration

* Fix

* Add 404 route
This commit is contained in:
Bruce Berrios 2022-02-28 06:37:05 -05:00 committed by GitHub
parent d958b2b48a
commit 182d0b6b22
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 430 additions and 212 deletions

View file

@ -0,0 +1,27 @@
import { MonkeyResponse } from "../../handlers/monkey-response";
class ApeKeysController {
static async getApeKey(_req: MonkeyTypes.Request): Promise<MonkeyResponse> {
return new MonkeyResponse("ApeKey retrieved");
}
static async generateApeKey(
_req: MonkeyTypes.Request
): Promise<MonkeyResponse> {
return new MonkeyResponse("ApeKey generated");
}
static async updateApeKey(
_req: MonkeyTypes.Request
): Promise<MonkeyResponse> {
return new MonkeyResponse("ApeKey updated");
}
static async deleteApeKey(
_req: MonkeyTypes.Request
): Promise<MonkeyResponse> {
return new MonkeyResponse("ApeKey deleted");
}
}
export default ApeKeysController;

View file

@ -0,0 +1,80 @@
import joi from "joi";
import { Router } from "express";
import {
asyncHandler,
validateConfiguration,
validateRequest,
} from "../../middlewares/api-utils";
import { authenticateRequest } from "../../middlewares/auth";
import ApeKeysController from "../controllers/ape-keys";
import * as RateLimit from "../../middlewares/rate-limit";
const apeKeyNameSchema = joi
.string()
.regex(/^[0-9a-zA-Z_.-]+$/)
.max(20)
.messages({
"string.pattern.base": "Invalid ApeKey name",
"string.max": "ApeKey name exceeds maximum of 20 characters",
});
const router = Router();
router.use(
validateConfiguration({
criteria: (configuration) => {
return configuration.apeKeys.endpointsEnabled;
},
invalidMessage: "ApeKeys are currently disabled.",
})
);
router.get(
"/",
RateLimit.apeKeysGet,
authenticateRequest(),
asyncHandler(ApeKeysController.getApeKey)
);
router.post(
"/",
RateLimit.apeKeysGenerate,
authenticateRequest(),
validateRequest({
body: {
name: apeKeyNameSchema.required(),
enabled: joi.boolean().required(),
},
}),
asyncHandler(ApeKeysController.generateApeKey)
);
router.patch(
"/:apeKeyId",
RateLimit.apeKeysUpdate,
authenticateRequest(),
validateRequest({
params: {
apeKeyId: joi.string().required(),
},
body: {
name: apeKeyNameSchema,
enabled: joi.boolean(),
},
}),
asyncHandler(ApeKeysController.updateApeKey)
);
router.delete(
"/:apeKeyId",
RateLimit.apeKeysDelete,
authenticateRequest(),
validateRequest({
params: {
apeKeyId: joi.string().required(),
},
}),
asyncHandler(ApeKeysController.deleteApeKey)
);
export default router;

View file

@ -5,6 +5,7 @@ import presets from "./presets";
import psas from "./psas";
import leaderboards from "./leaderboards";
import quotes from "./quotes";
import apeKeys from "./ape-keys";
import { asyncHandler } from "../../middlewares/api-utils";
import { MonkeyResponse } from "../../handlers/monkey-response";
import { Application, NextFunction, Response } from "express";
@ -22,6 +23,7 @@ const API_ROUTE_MAP = {
"/psas": psas,
"/leaderboards": leaderboards,
"/quotes": quotes,
"/ape-keys": apeKeys,
};
function addApiRoutes(app: Application): void {
@ -73,6 +75,16 @@ function addApiRoutes(app: Application): void {
const router = API_ROUTE_MAP[route];
app.use(apiRoute, router);
});
app.use(
asyncHandler(async (req, _res) => {
return new MonkeyResponse(
`Unknown request URL (${req.method}: ${req.path})`,
null,
404
);
})
);
}
export default addApiRoutes;

View file

@ -16,8 +16,10 @@ const BASE_CONFIGURATION: MonkeyTypes.Configuration = {
resultObjectHashCheck: {
enabled: false,
},
monkeyTokens: {
enabled: false,
apeKeys: {
endpointsEnabled: false,
acceptKeys: false,
maxKeysPerUser: 0,
},
enableSavingResults: {
enabled: false,

View file

@ -4,12 +4,12 @@ import { NextFunction, Response, Handler } from "express";
interface RequestAuthenticationOptions {
isPublic?: boolean;
acceptMonkeyTokens?: boolean;
acceptApeKeys?: boolean;
}
const DEFAULT_OPTIONS: RequestAuthenticationOptions = {
isPublic: false,
acceptMonkeyTokens: false,
acceptApeKeys: false,
};
function authenticateRequest(authOptions = DEFAULT_OPTIONS): Handler {
@ -28,7 +28,11 @@ function authenticateRequest(authOptions = DEFAULT_OPTIONS): Handler {
let token: MonkeyTypes.DecodedToken = {};
if (authHeader) {
token = await authenticateWithAuthHeader(authHeader, options);
token = await authenticateWithAuthHeader(
authHeader,
req.ctx.configuration,
options
);
} else if (options.isPublic) {
return next();
} else if (process.env.MODE === "dev") {
@ -72,6 +76,7 @@ function authenticateWithBody(
async function authenticateWithAuthHeader(
authHeader: string,
configuration: MonkeyTypes.Configuration,
options: RequestAuthenticationOptions
): Promise<MonkeyTypes.DecodedToken> {
const token = authHeader.split(" ");
@ -82,8 +87,8 @@ async function authenticateWithAuthHeader(
switch (authScheme) {
case "Bearer":
return await authenticateWithBearerToken(credentials);
case "MonkeyToken":
return await authenticateWithMonkeyToken(credentials, options);
case "ApeKey":
return await authenticateWithApeKey(credentials, configuration, options);
}
throw new MonkeyError(
@ -126,15 +131,19 @@ async function authenticateWithBearerToken(
}
}
async function authenticateWithMonkeyToken(
token: string,
async function authenticateWithApeKey(
key: string,
configuration: MonkeyTypes.Configuration,
options: RequestAuthenticationOptions
): Promise<MonkeyTypes.DecodedToken> {
if (!options.acceptMonkeyTokens) {
throw new MonkeyError(401, "This endpoint does not accept MonkeyTokens.");
if (!configuration.apeKeys.acceptKeys) {
throw new MonkeyError(403, "ApeKeys are not being accepted at this time.");
}
if (!options.acceptApeKeys) {
throw new MonkeyError(401, "This endpoint does not accept ApeKeys.");
}
throw new MonkeyError(401, "MonkeyTokens are not implemented.");
throw new MonkeyError(401, "ApeKeys are not implemented.");
}
export { authenticateRequest };

View file

@ -20,16 +20,18 @@ const customHandler = (
throw new MonkeyError(429, "Too many attempts, please try again later.");
};
const ONE_HOUR = 1000 * 60 * 60;
// Config Routing
export const configUpdate = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 500 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const configGet = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 120 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
@ -37,7 +39,7 @@ export const configGet = rateLimit({
// Leaderboards Routing
export const leaderboardsGet = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 60 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
@ -45,21 +47,21 @@ export const leaderboardsGet = rateLimit({
// New Quotes Routing
export const newQuotesGet = rateLimit({
windowMs: 60 * 60 * 1000,
windowMs: ONE_HOUR,
max: 500 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const newQuotesAdd = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 60 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const newQuotesAction = rateLimit({
windowMs: 60 * 60 * 1000,
windowMs: ONE_HOUR,
max: 500 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
@ -67,14 +69,14 @@ export const newQuotesAction = rateLimit({
// Quote Ratings Routing
export const quoteRatingsGet = rateLimit({
windowMs: 60 * 60 * 1000,
windowMs: ONE_HOUR,
max: 500 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const quoteRatingsSubmit = rateLimit({
windowMs: 60 * 60 * 1000,
windowMs: ONE_HOUR,
max: 500 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
@ -90,28 +92,28 @@ export const quoteReportSubmit = rateLimit({
// Presets Routing
export const presetsGet = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 60 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const presetsAdd = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 60 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const presetsRemove = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 60 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const presetsEdit = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 60 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
@ -127,42 +129,42 @@ export const psaGet = rateLimit({
// Results Routing
export const resultsGet = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 60 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const resultsAdd = rateLimit({
windowMs: 60 * 60 * 1000,
windowMs: ONE_HOUR,
max: 500 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const resultsTagsUpdate = rateLimit({
windowMs: 60 * 60 * 1000,
windowMs: ONE_HOUR,
max: 30 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const resultsDeleteAll = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 10 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const resultsLeaderboardGet = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 60 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const resultsLeaderboardQualificationGet = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 60 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
@ -170,21 +172,21 @@ export const resultsLeaderboardQualificationGet = rateLimit({
// Users Routing
export const userGet = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 60 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const userSignup = rateLimit({
windowMs: 24 * 60 * 60 * 1000, // 1 day
windowMs: 24 * ONE_HOUR, // 1 day
max: 3 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const userDelete = rateLimit({
windowMs: 24 * 60 * 60 * 1000, // 1 day
windowMs: 24 * ONE_HOUR, // 1 day
max: 3 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
@ -198,7 +200,7 @@ export const userCheckName = rateLimit({
});
export const userUpdateName = rateLimit({
windowMs: 24 * 60 * 60 * 1000, // 1 day
windowMs: 24 * ONE_HOUR, // 1 day
max: 3 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
@ -212,56 +214,56 @@ export const userUpdateLBMemory = rateLimit({
});
export const userUpdateEmail = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 60 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const userClearPB = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 60 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const userTagsGet = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 60 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const userTagsRemove = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 30 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const userTagsClearPB = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 60 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const userTagsEdit = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 30 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const userTagsAdd = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 30 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const userDiscordLink = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 15 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
@ -270,8 +272,27 @@ export const userDiscordLink = rateLimit({
export const usersTagsEdit = userDiscordLink;
export const userDiscordUnlink = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min
windowMs: ONE_HOUR,
max: 15 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
// ApeKeys Routing
export const apeKeysGet = rateLimit({
windowMs: ONE_HOUR,
max: 120 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const apeKeysGenerate = rateLimit({
windowMs: ONE_HOUR,
max: 15 * REQUEST_MULTIPLIER,
keyGenerator: getAddress,
handler: customHandler,
});
export const apeKeysUpdate = apeKeysGenerate;
export const apeKeysDelete = apeKeysGenerate;

View file

@ -14,7 +14,7 @@
"dotenv": "10.0.0",
"express": "4.17.1",
"express-rate-limit": "6.2.1",
"firebase-admin": "9.11.0",
"firebase-admin": "10.0.2",
"helmet": "4.6.0",
"joi": "17.6.0",
"lodash": "4.17.21",
@ -43,11 +43,35 @@
"npm": "8.1.2"
}
},
"node_modules/@firebase/app": {
"version": "0.7.17",
"resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.7.17.tgz",
"integrity": "sha512-OnZab790eMwRxkUs7o/kgniAzSBxecDTGEk1PVhiG0HQhKrIf+R7lgqOZHDb/2GJsX12jby1p/Z5+WJCBxVbJQ==",
"peer": true,
"dependencies": {
"@firebase/component": "0.5.10",
"@firebase/logger": "0.3.2",
"@firebase/util": "1.4.3",
"tslib": "^2.1.0"
}
},
"node_modules/@firebase/app-compat": {
"version": "0.1.18",
"resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.1.18.tgz",
"integrity": "sha512-YXmMLQro2g2xlNnzB6zVxYoFx9sJS/JDEQy6vsj3FpMUuARaImipL6W8KuGfH+tJ3M+q38qRaFROk5gK6PoCrQ==",
"peer": true,
"dependencies": {
"@firebase/app": "0.7.17",
"@firebase/component": "0.5.10",
"@firebase/logger": "0.3.2",
"@firebase/util": "1.4.3",
"tslib": "^2.1.0"
}
},
"node_modules/@firebase/app-types": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.7.0.tgz",
"integrity": "sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg==",
"peer": true
"integrity": "sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg=="
},
"node_modules/@firebase/auth-interop-types": {
"version": "0.1.6",
@ -59,58 +83,72 @@
}
},
"node_modules/@firebase/component": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.5.tgz",
"integrity": "sha512-L41SdS/4a164jx2iGfakJgaBUPPBI3DI+RrUlmh3oHSUljTeCwfj/Nhcv3S7e2lyXsGFJtAyepfPUx4IQ05crw==",
"version": "0.5.10",
"resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.10.tgz",
"integrity": "sha512-mzUpg6rsBbdQJvAdu1rNWabU3O7qdd+B+/ubE1b+pTbBKfw5ySRpRRE6sKcZ/oQuwLh0HHB6FRJHcylmI7jDzA==",
"dependencies": {
"@firebase/util": "1.2.0",
"@firebase/util": "1.4.3",
"tslib": "^2.1.0"
}
},
"node_modules/@firebase/database": {
"version": "0.10.9",
"resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.10.9.tgz",
"integrity": "sha512-Jxi9SiE4cNOftO9YKlG71ccyWFw4kSM9AG/xYu6vWXUGBr39Uw1TvYougANOcU21Q0TP4J08VPGnOnpXk/FGbQ==",
"version": "0.12.5",
"resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.12.5.tgz",
"integrity": "sha512-1Pd2jYqvqZI7SQWAiXbTZxmsOa29PyOaPiUtr8pkLSfLp4AeyMBegYAXCLYLW6BNhKn3zNKFkxYDxYHq4q+Ixg==",
"dependencies": {
"@firebase/auth-interop-types": "0.1.6",
"@firebase/component": "0.5.5",
"@firebase/database-types": "0.7.3",
"@firebase/logger": "0.2.6",
"@firebase/util": "1.2.0",
"faye-websocket": "0.11.3",
"@firebase/component": "0.5.10",
"@firebase/logger": "0.3.2",
"@firebase/util": "1.4.3",
"faye-websocket": "0.11.4",
"tslib": "^2.1.0"
}
},
"node_modules/@firebase/database-types": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.7.3.tgz",
"integrity": "sha512-dSOJmhKQ0nL8O4EQMRNGpSExWCXeHtH57gGg0BfNAdWcKhC8/4Y+qfKLfWXzyHvrSecpLmO0SmAi/iK2D5fp5A==",
"node_modules/@firebase/database-compat": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.1.5.tgz",
"integrity": "sha512-UVxkHL24sZfsjsjs+yiKIdYdrWXHrLxSFCYNdwNXDlTkAc0CWP9AAY3feLhBVpUKk+4Cj0I4sGnyIm2C1ltAYg==",
"dependencies": {
"@firebase/app-types": "0.6.3"
"@firebase/component": "0.5.10",
"@firebase/database": "0.12.5",
"@firebase/database-types": "0.9.4",
"@firebase/logger": "0.3.2",
"@firebase/util": "1.4.3",
"tslib": "^2.1.0"
},
"peerDependencies": {
"@firebase/app-compat": "0.x"
}
},
"node_modules/@firebase/database-types/node_modules/@firebase/app-types": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.3.tgz",
"integrity": "sha512-/M13DPPati7FQHEQ9Minjk1HGLm/4K4gs9bR4rzLCWJg64yGtVC0zNg9gDpkw9yc2cvol/mNFxqTtd4geGrwdw=="
"node_modules/@firebase/database-types": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.9.4.tgz",
"integrity": "sha512-uAQuc6NUZ5Oh/cWZPeMValtcZ+4L1stgKOeYvz7mLn8+s03tnCDL2N47OLCHdntktVkhImQTwGNARgqhIhtNeA==",
"dependencies": {
"@firebase/app-types": "0.7.0",
"@firebase/util": "1.4.3"
}
},
"node_modules/@firebase/logger": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.2.6.tgz",
"integrity": "sha512-KIxcUvW/cRGWlzK9Vd2KB864HlUnCfdTH0taHE0sXW5Xl7+W68suaeau1oKNEqmc3l45azkd4NzXTCWZRZdXrw=="
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.3.2.tgz",
"integrity": "sha512-lzLrcJp9QBWpo40OcOM9B8QEtBw2Fk1zOZQdvv+rWS6gKmhQBCEMc4SMABQfWdjsylBcDfniD1Q+fUX1dcBTXA==",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/@firebase/util": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.2.0.tgz",
"integrity": "sha512-8W9TTGImXr9cu+oyjBJ7yjoEd/IVAv0pBZA4c1uIuKrpGZi2ee38m+8xlZOBRmsAaOU/tR9DXz1WF/oeM6Fb7Q==",
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.4.3.tgz",
"integrity": "sha512-gQJl6r0a+MElLQEyU8Dx0kkC2coPj67f/zKZrGR7z7WpLgVanhaCUqEsptwpwoxi9RMFIaebleG+C9xxoARq+Q==",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/@google-cloud/common": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.9.0.tgz",
"integrity": "sha512-R9PfmCKbpOizvcLY+fz/TS4HdOQhvmf4EY4xEXvWnotGbGXujuTLJTJ2URy8BGT8TDxlh6gjjfEwjJ8McnNPIg==",
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.10.0.tgz",
"integrity": "sha512-XMbJYMh/ZSaZnbnrrOFfR/oQrb0SxG4qh6hDisWCoEbFcBHV0qHQo4uXfeMCzolx2Mfkh6VDaOGg+hyJsmxrlw==",
"optional": true,
"dependencies": {
"@google-cloud/projectify": "^2.0.0",
@ -119,7 +157,7 @@
"duplexify": "^4.1.1",
"ent": "^2.2.0",
"extend": "^3.0.2",
"google-auth-library": "^7.9.2",
"google-auth-library": "^7.14.0",
"retry-request": "^4.2.2",
"teeny-request": "^7.0.0"
},
@ -143,9 +181,9 @@
}
},
"node_modules/@google-cloud/paginator": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.6.tgz",
"integrity": "sha512-XCTm/GfQIlc1ZxpNtTSs/mnZxC2cePNhxU3X8EzHXKIJ2JFncmJj2Fcd2IP+gbmZaSZnY0juFxbUCkIeuu/2eQ==",
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.7.tgz",
"integrity": "sha512-jJNutk0arIQhmpUUQJPJErsojqo834KcyB6X7a1mxuic8i1tKXxde8E69IZxNZawRIlZdIK2QY4WALvlK5MzYQ==",
"optional": true,
"dependencies": {
"arrify": "^2.0.0",
@ -174,13 +212,13 @@
}
},
"node_modules/@google-cloud/storage": {
"version": "5.18.1",
"resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.18.1.tgz",
"integrity": "sha512-EeVIarDb6u9vE5Se3YaXA8tuW8Ae2xmYLHy43doutTwzkXwizGXVS2Qmc2pouq9ln8qMD9A2f3arvhgAPtK9LQ==",
"version": "5.18.2",
"resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.18.2.tgz",
"integrity": "sha512-hL/6epBF2uPt7YtJoOKI6mVxe6RsKBs7S8o2grE0bFGdQKSOngVHBcstH8jDw7aN2rXGouA2TfVTxH+VapY5cg==",
"optional": true,
"dependencies": {
"@google-cloud/common": "^3.8.1",
"@google-cloud/paginator": "^3.0.0",
"@google-cloud/paginator": "^3.0.7",
"@google-cloud/promisify": "^2.0.0",
"abort-controller": "^3.0.0",
"arrify": "^2.0.0",
@ -219,9 +257,9 @@
}
},
"node_modules/@grpc/grpc-js": {
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.5.4.tgz",
"integrity": "sha512-+nJTOsqpFAXnfFrMZ7Too4XXZ/J9O+8jYvSoaunupoC7I7b9H4iex1BRsbTdOmiowfPGJrWit7jUPmbENSUSpw==",
"version": "1.5.7",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.5.7.tgz",
"integrity": "sha512-RAlSbZ9LXo0wNoHKeUlwP9dtGgVBDUbnBKFpfAv5iSqMG4qWz9um2yLH215+Wow1I48etIa1QMS+WAGmsE/7HQ==",
"optional": true,
"dependencies": {
"@grpc/proto-loader": "^0.6.4",
@ -479,9 +517,9 @@
}
},
"node_modules/@types/express-unless": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.2.tgz",
"integrity": "sha512-Q74UyYRX/zIgl1HSp9tUX2PlG8glkVm+59r7aK4KGKzC5jqKIOX6rrVLRQrzpZUQ84VukHtRoeAuon2nIssHPQ==",
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.3.tgz",
"integrity": "sha512-TyPLQaF6w8UlWdv4gj8i46B+INBVzURBNRahCozCSXfsK2VTlL1wNyTlMKw817VHygBtlcl5jfnPadlydr06Yw==",
"dependencies": {
"@types/express": "*"
}
@ -1221,9 +1259,9 @@
}
},
"node_modules/date-and-time": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-2.1.0.tgz",
"integrity": "sha512-X/b2gM7e8zQ7siiE0DhRLeNMpuCkIqec5Jnx4GMk/HWB71a6e5Lz48mH9/GIS/hpLsBRFZfMF1gjXBkY0vq5oA==",
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-2.2.1.tgz",
"integrity": "sha512-i5lrLPmRbdtb9/Tcu+NWWvff29ejNZtnL/6TI5VbhuPtqgea7bovY0F2AtFSX9QDQEQLUtqJ3R8ypM2c6alGoA==",
"optional": true
},
"node_modules/debug": {
@ -1503,9 +1541,9 @@
"optional": true
},
"node_modules/faye-websocket": {
"version": "0.11.3",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz",
"integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==",
"version": "0.11.4",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
"integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
"dependencies": {
"websocket-driver": ">=0.5.1"
},
@ -1542,20 +1580,20 @@
}
},
"node_modules/firebase-admin": {
"version": "9.11.0",
"resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.11.0.tgz",
"integrity": "sha512-68fXdwcKF99LkWBE33M5hnLwjvGpbCRznIOtZVsiBqZdM9iwxlTfNEpAckh++o3GdJcSLRUWmIN+MKqPUsxoCA==",
"version": "10.0.2",
"resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-10.0.2.tgz",
"integrity": "sha512-MLH0SPmC4L0aCHvPjs1KThraru/T84T3hxiPY3uCH7NZEgE/T5n4GwecwU3RcM3X+br75BIBY7qhaR5uCxhdXA==",
"dependencies": {
"@firebase/database": "^0.10.0",
"@firebase/database-types": "^0.7.2",
"@firebase/database-compat": "^0.1.1",
"@firebase/database-types": "^0.9.3",
"@types/node": ">=12.12.47",
"dicer": "^0.3.0",
"jsonwebtoken": "^8.5.1",
"jwks-rsa": "^2.0.2",
"node-forge": "^0.10.0"
"node-forge": "^1.0.0"
},
"engines": {
"node": ">=10.13.0"
"node": ">=12.7.0"
},
"optionalDependencies": {
"@google-cloud/firestore": "^4.5.0",
@ -1720,9 +1758,9 @@
}
},
"node_modules/google-auth-library": {
"version": "7.11.0",
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.11.0.tgz",
"integrity": "sha512-3S5jn2quRumvh9F/Ubf7GFrIq71HZ5a6vqosgdIu105kkk0WtSqc2jGCRqtWWOLRS8SX3AHACMOEDxhyWAQIcg==",
"version": "7.14.0",
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.14.0.tgz",
"integrity": "sha512-or8r7qUqGVI3W8lVSdPh0ZpeFyQHeE73g5c0p+bLNTTUFXJ+GSeDQmZRZ2p4H8cF/RJYa4PNvi/A1ar1uVNLFA==",
"optional": true,
"dependencies": {
"arrify": "^2.0.0",
@ -1740,9 +1778,9 @@
}
},
"node_modules/google-gax": {
"version": "2.29.5",
"resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.29.5.tgz",
"integrity": "sha512-wJI+rgqujcl4/0eO4sRIwXAJAD+G8dFRqvGxc2lUuZtdzOToc5NHYbrTvplWQVO6Lw1YNsk9u1pKN3HcXembJg==",
"version": "2.30.0",
"resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.30.0.tgz",
"integrity": "sha512-JcZGDuSOzhPwOJfbK80cyyGLZkrlLBTiwfqrW46sC0I9h3FtFmbN7FwIQ3PHreYiE6iVK4InfEZiTp4laOmPfA==",
"optional": true,
"dependencies": {
"@grpc/grpc-js": "~1.5.0",
@ -1751,10 +1789,10 @@
"abort-controller": "^3.0.0",
"duplexify": "^4.0.0",
"fast-text-encoding": "^1.0.3",
"google-auth-library": "^7.6.1",
"google-auth-library": "^7.14.0",
"is-stream-ended": "^0.1.4",
"node-fetch": "^2.6.1",
"object-hash": "^2.1.1",
"object-hash": "^3.0.0",
"proto3-json-serializer": "^0.1.8",
"protobufjs": "6.11.2",
"retry-request": "^4.0.0"
@ -1781,15 +1819,6 @@
"node": ">=10"
}
},
"node_modules/google-p12-pem/node_modules/node-forge": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.2.1.tgz",
"integrity": "sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w==",
"optional": true,
"engines": {
"node": ">= 6.13.0"
}
},
"node_modules/got": {
"version": "9.6.0",
"resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
@ -2752,11 +2781,11 @@
}
},
"node_modules/node-forge": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
"integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.2.1.tgz",
"integrity": "sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w==",
"engines": {
"node": ">= 6.0.0"
"node": ">= 6.13.0"
}
},
"node_modules/node-object-hash": {
@ -2854,9 +2883,9 @@
}
},
"node_modules/object-hash": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz",
"integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
"optional": true,
"engines": {
"node": ">= 6"
@ -4107,11 +4136,35 @@
}
},
"dependencies": {
"@firebase/app": {
"version": "0.7.17",
"resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.7.17.tgz",
"integrity": "sha512-OnZab790eMwRxkUs7o/kgniAzSBxecDTGEk1PVhiG0HQhKrIf+R7lgqOZHDb/2GJsX12jby1p/Z5+WJCBxVbJQ==",
"peer": true,
"requires": {
"@firebase/component": "0.5.10",
"@firebase/logger": "0.3.2",
"@firebase/util": "1.4.3",
"tslib": "^2.1.0"
}
},
"@firebase/app-compat": {
"version": "0.1.18",
"resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.1.18.tgz",
"integrity": "sha512-YXmMLQro2g2xlNnzB6zVxYoFx9sJS/JDEQy6vsj3FpMUuARaImipL6W8KuGfH+tJ3M+q38qRaFROk5gK6PoCrQ==",
"peer": true,
"requires": {
"@firebase/app": "0.7.17",
"@firebase/component": "0.5.10",
"@firebase/logger": "0.3.2",
"@firebase/util": "1.4.3",
"tslib": "^2.1.0"
}
},
"@firebase/app-types": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.7.0.tgz",
"integrity": "sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg==",
"peer": true
"integrity": "sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg=="
},
"@firebase/auth-interop-types": {
"version": "0.1.6",
@ -4120,60 +4173,69 @@
"requires": {}
},
"@firebase/component": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.5.tgz",
"integrity": "sha512-L41SdS/4a164jx2iGfakJgaBUPPBI3DI+RrUlmh3oHSUljTeCwfj/Nhcv3S7e2lyXsGFJtAyepfPUx4IQ05crw==",
"version": "0.5.10",
"resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.10.tgz",
"integrity": "sha512-mzUpg6rsBbdQJvAdu1rNWabU3O7qdd+B+/ubE1b+pTbBKfw5ySRpRRE6sKcZ/oQuwLh0HHB6FRJHcylmI7jDzA==",
"requires": {
"@firebase/util": "1.2.0",
"@firebase/util": "1.4.3",
"tslib": "^2.1.0"
}
},
"@firebase/database": {
"version": "0.10.9",
"resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.10.9.tgz",
"integrity": "sha512-Jxi9SiE4cNOftO9YKlG71ccyWFw4kSM9AG/xYu6vWXUGBr39Uw1TvYougANOcU21Q0TP4J08VPGnOnpXk/FGbQ==",
"version": "0.12.5",
"resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.12.5.tgz",
"integrity": "sha512-1Pd2jYqvqZI7SQWAiXbTZxmsOa29PyOaPiUtr8pkLSfLp4AeyMBegYAXCLYLW6BNhKn3zNKFkxYDxYHq4q+Ixg==",
"requires": {
"@firebase/auth-interop-types": "0.1.6",
"@firebase/component": "0.5.5",
"@firebase/database-types": "0.7.3",
"@firebase/logger": "0.2.6",
"@firebase/util": "1.2.0",
"faye-websocket": "0.11.3",
"@firebase/component": "0.5.10",
"@firebase/logger": "0.3.2",
"@firebase/util": "1.4.3",
"faye-websocket": "0.11.4",
"tslib": "^2.1.0"
}
},
"@firebase/database-compat": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.1.5.tgz",
"integrity": "sha512-UVxkHL24sZfsjsjs+yiKIdYdrWXHrLxSFCYNdwNXDlTkAc0CWP9AAY3feLhBVpUKk+4Cj0I4sGnyIm2C1ltAYg==",
"requires": {
"@firebase/component": "0.5.10",
"@firebase/database": "0.12.5",
"@firebase/database-types": "0.9.4",
"@firebase/logger": "0.3.2",
"@firebase/util": "1.4.3",
"tslib": "^2.1.0"
}
},
"@firebase/database-types": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.7.3.tgz",
"integrity": "sha512-dSOJmhKQ0nL8O4EQMRNGpSExWCXeHtH57gGg0BfNAdWcKhC8/4Y+qfKLfWXzyHvrSecpLmO0SmAi/iK2D5fp5A==",
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.9.4.tgz",
"integrity": "sha512-uAQuc6NUZ5Oh/cWZPeMValtcZ+4L1stgKOeYvz7mLn8+s03tnCDL2N47OLCHdntktVkhImQTwGNARgqhIhtNeA==",
"requires": {
"@firebase/app-types": "0.6.3"
},
"dependencies": {
"@firebase/app-types": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.3.tgz",
"integrity": "sha512-/M13DPPati7FQHEQ9Minjk1HGLm/4K4gs9bR4rzLCWJg64yGtVC0zNg9gDpkw9yc2cvol/mNFxqTtd4geGrwdw=="
}
"@firebase/app-types": "0.7.0",
"@firebase/util": "1.4.3"
}
},
"@firebase/logger": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.2.6.tgz",
"integrity": "sha512-KIxcUvW/cRGWlzK9Vd2KB864HlUnCfdTH0taHE0sXW5Xl7+W68suaeau1oKNEqmc3l45azkd4NzXTCWZRZdXrw=="
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.3.2.tgz",
"integrity": "sha512-lzLrcJp9QBWpo40OcOM9B8QEtBw2Fk1zOZQdvv+rWS6gKmhQBCEMc4SMABQfWdjsylBcDfniD1Q+fUX1dcBTXA==",
"requires": {
"tslib": "^2.1.0"
}
},
"@firebase/util": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.2.0.tgz",
"integrity": "sha512-8W9TTGImXr9cu+oyjBJ7yjoEd/IVAv0pBZA4c1uIuKrpGZi2ee38m+8xlZOBRmsAaOU/tR9DXz1WF/oeM6Fb7Q==",
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.4.3.tgz",
"integrity": "sha512-gQJl6r0a+MElLQEyU8Dx0kkC2coPj67f/zKZrGR7z7WpLgVanhaCUqEsptwpwoxi9RMFIaebleG+C9xxoARq+Q==",
"requires": {
"tslib": "^2.1.0"
}
},
"@google-cloud/common": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.9.0.tgz",
"integrity": "sha512-R9PfmCKbpOizvcLY+fz/TS4HdOQhvmf4EY4xEXvWnotGbGXujuTLJTJ2URy8BGT8TDxlh6gjjfEwjJ8McnNPIg==",
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.10.0.tgz",
"integrity": "sha512-XMbJYMh/ZSaZnbnrrOFfR/oQrb0SxG4qh6hDisWCoEbFcBHV0qHQo4uXfeMCzolx2Mfkh6VDaOGg+hyJsmxrlw==",
"optional": true,
"requires": {
"@google-cloud/projectify": "^2.0.0",
@ -4182,7 +4244,7 @@
"duplexify": "^4.1.1",
"ent": "^2.2.0",
"extend": "^3.0.2",
"google-auth-library": "^7.9.2",
"google-auth-library": "^7.14.0",
"retry-request": "^4.2.2",
"teeny-request": "^7.0.0"
}
@ -4200,9 +4262,9 @@
}
},
"@google-cloud/paginator": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.6.tgz",
"integrity": "sha512-XCTm/GfQIlc1ZxpNtTSs/mnZxC2cePNhxU3X8EzHXKIJ2JFncmJj2Fcd2IP+gbmZaSZnY0juFxbUCkIeuu/2eQ==",
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.7.tgz",
"integrity": "sha512-jJNutk0arIQhmpUUQJPJErsojqo834KcyB6X7a1mxuic8i1tKXxde8E69IZxNZawRIlZdIK2QY4WALvlK5MzYQ==",
"optional": true,
"requires": {
"arrify": "^2.0.0",
@ -4222,13 +4284,13 @@
"optional": true
},
"@google-cloud/storage": {
"version": "5.18.1",
"resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.18.1.tgz",
"integrity": "sha512-EeVIarDb6u9vE5Se3YaXA8tuW8Ae2xmYLHy43doutTwzkXwizGXVS2Qmc2pouq9ln8qMD9A2f3arvhgAPtK9LQ==",
"version": "5.18.2",
"resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.18.2.tgz",
"integrity": "sha512-hL/6epBF2uPt7YtJoOKI6mVxe6RsKBs7S8o2grE0bFGdQKSOngVHBcstH8jDw7aN2rXGouA2TfVTxH+VapY5cg==",
"optional": true,
"requires": {
"@google-cloud/common": "^3.8.1",
"@google-cloud/paginator": "^3.0.0",
"@google-cloud/paginator": "^3.0.7",
"@google-cloud/promisify": "^2.0.0",
"abort-controller": "^3.0.0",
"arrify": "^2.0.0",
@ -4260,9 +4322,9 @@
}
},
"@grpc/grpc-js": {
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.5.4.tgz",
"integrity": "sha512-+nJTOsqpFAXnfFrMZ7Too4XXZ/J9O+8jYvSoaunupoC7I7b9H4iex1BRsbTdOmiowfPGJrWit7jUPmbENSUSpw==",
"version": "1.5.7",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.5.7.tgz",
"integrity": "sha512-RAlSbZ9LXo0wNoHKeUlwP9dtGgVBDUbnBKFpfAv5iSqMG4qWz9um2yLH215+Wow1I48etIa1QMS+WAGmsE/7HQ==",
"optional": true,
"requires": {
"@grpc/proto-loader": "^0.6.4",
@ -4493,9 +4555,9 @@
}
},
"@types/express-unless": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.2.tgz",
"integrity": "sha512-Q74UyYRX/zIgl1HSp9tUX2PlG8glkVm+59r7aK4KGKzC5jqKIOX6rrVLRQrzpZUQ84VukHtRoeAuon2nIssHPQ==",
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.3.tgz",
"integrity": "sha512-TyPLQaF6w8UlWdv4gj8i46B+INBVzURBNRahCozCSXfsK2VTlL1wNyTlMKw817VHygBtlcl5jfnPadlydr06Yw==",
"requires": {
"@types/express": "*"
}
@ -5065,9 +5127,9 @@
}
},
"date-and-time": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-2.1.0.tgz",
"integrity": "sha512-X/b2gM7e8zQ7siiE0DhRLeNMpuCkIqec5Jnx4GMk/HWB71a6e5Lz48mH9/GIS/hpLsBRFZfMF1gjXBkY0vq5oA==",
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-2.2.1.tgz",
"integrity": "sha512-i5lrLPmRbdtb9/Tcu+NWWvff29ejNZtnL/6TI5VbhuPtqgea7bovY0F2AtFSX9QDQEQLUtqJ3R8ypM2c6alGoA==",
"optional": true
},
"debug": {
@ -5297,9 +5359,9 @@
"optional": true
},
"faye-websocket": {
"version": "0.11.3",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz",
"integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==",
"version": "0.11.4",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
"integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
"requires": {
"websocket-driver": ">=0.5.1"
}
@ -5327,19 +5389,19 @@
}
},
"firebase-admin": {
"version": "9.11.0",
"resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.11.0.tgz",
"integrity": "sha512-68fXdwcKF99LkWBE33M5hnLwjvGpbCRznIOtZVsiBqZdM9iwxlTfNEpAckh++o3GdJcSLRUWmIN+MKqPUsxoCA==",
"version": "10.0.2",
"resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-10.0.2.tgz",
"integrity": "sha512-MLH0SPmC4L0aCHvPjs1KThraru/T84T3hxiPY3uCH7NZEgE/T5n4GwecwU3RcM3X+br75BIBY7qhaR5uCxhdXA==",
"requires": {
"@firebase/database": "^0.10.0",
"@firebase/database-types": "^0.7.2",
"@firebase/database-compat": "^0.1.1",
"@firebase/database-types": "^0.9.3",
"@google-cloud/firestore": "^4.5.0",
"@google-cloud/storage": "^5.3.0",
"@types/node": ">=12.12.47",
"dicer": "^0.3.0",
"jsonwebtoken": "^8.5.1",
"jwks-rsa": "^2.0.2",
"node-forge": "^0.10.0"
"node-forge": "^1.0.0"
}
},
"forever-agent": {
@ -5454,9 +5516,9 @@
}
},
"google-auth-library": {
"version": "7.11.0",
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.11.0.tgz",
"integrity": "sha512-3S5jn2quRumvh9F/Ubf7GFrIq71HZ5a6vqosgdIu105kkk0WtSqc2jGCRqtWWOLRS8SX3AHACMOEDxhyWAQIcg==",
"version": "7.14.0",
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.14.0.tgz",
"integrity": "sha512-or8r7qUqGVI3W8lVSdPh0ZpeFyQHeE73g5c0p+bLNTTUFXJ+GSeDQmZRZ2p4H8cF/RJYa4PNvi/A1ar1uVNLFA==",
"optional": true,
"requires": {
"arrify": "^2.0.0",
@ -5471,9 +5533,9 @@
}
},
"google-gax": {
"version": "2.29.5",
"resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.29.5.tgz",
"integrity": "sha512-wJI+rgqujcl4/0eO4sRIwXAJAD+G8dFRqvGxc2lUuZtdzOToc5NHYbrTvplWQVO6Lw1YNsk9u1pKN3HcXembJg==",
"version": "2.30.0",
"resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.30.0.tgz",
"integrity": "sha512-JcZGDuSOzhPwOJfbK80cyyGLZkrlLBTiwfqrW46sC0I9h3FtFmbN7FwIQ3PHreYiE6iVK4InfEZiTp4laOmPfA==",
"optional": true,
"requires": {
"@grpc/grpc-js": "~1.5.0",
@ -5482,10 +5544,10 @@
"abort-controller": "^3.0.0",
"duplexify": "^4.0.0",
"fast-text-encoding": "^1.0.3",
"google-auth-library": "^7.6.1",
"google-auth-library": "^7.14.0",
"is-stream-ended": "^0.1.4",
"node-fetch": "^2.6.1",
"object-hash": "^2.1.1",
"object-hash": "^3.0.0",
"proto3-json-serializer": "^0.1.8",
"protobufjs": "6.11.2",
"retry-request": "^4.0.0"
@ -5498,14 +5560,6 @@
"optional": true,
"requires": {
"node-forge": "^1.0.0"
},
"dependencies": {
"node-forge": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.2.1.tgz",
"integrity": "sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w==",
"optional": true
}
}
},
"got": {
@ -6255,9 +6309,9 @@
}
},
"node-forge": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
"integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA=="
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.2.1.tgz",
"integrity": "sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w=="
},
"node-object-hash": {
"version": "2.3.10",
@ -6323,9 +6377,9 @@
"version": "4.1.1"
},
"object-hash": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz",
"integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
"optional": true
},
"object-inspect": {

View file

@ -21,7 +21,7 @@
"dotenv": "10.0.0",
"express": "4.17.1",
"express-rate-limit": "6.2.1",
"firebase-admin": "9.11.0",
"firebase-admin": "10.0.2",
"helmet": "4.6.0",
"joi": "17.6.0",
"lodash": "4.17.21",

View file

@ -14,13 +14,16 @@ declare namespace MonkeyTypes {
resultObjectHashCheck: {
enabled: boolean;
};
monkeyTokens: {
enabled: boolean;
apeKeys: {
endpointsEnabled: boolean;
acceptKeys: boolean;
maxKeysPerUser: number;
};
enableSavingResults: {
enabled: boolean;
};
}
interface DecodedToken {
uid?: string;
email?: string;
@ -58,4 +61,14 @@ declare namespace MonkeyTypes {
quoteMod: boolean;
cannotReport: boolean;
}
interface ApeKey {
_id: string;
name: string;
hash: string;
uid: string;
createdOn: number;
modifiedOn: number;
enabled: boolean;
}
}