Part of AppLink login process

This commit is contained in:
simojenki
2021-02-21 09:35:34 +11:00
parent 302efd2878
commit c26a325ee1
20 changed files with 644 additions and 253 deletions

View File

@@ -8,19 +8,22 @@
"dependencies": { "dependencies": {
"@svrooij/sonos": "^2.3.0", "@svrooij/sonos": "^2.3.0",
"@types/express": "^4.17.11", "@types/express": "^4.17.11",
"@types/morgan": "^1.9.2",
"@types/node": "^14.14.22", "@types/node": "^14.14.22",
"@types/underscore": "1.10.24", "@types/underscore": "1.10.24",
"@types/uuid": "^8.3.0", "@types/uuid": "^8.3.0",
"axios": "^0.21.1", "axios": "^0.21.1",
"eta": "^1.12.1", "eta": "^1.12.1",
"express": "^4.17.1", "express": "^4.17.1",
"morgan": "^1.10.0",
"node-html-parser": "^2.1.0", "node-html-parser": "^2.1.0",
"soap": "^0.36.0", "soap": "^0.36.0",
"ts-md5": "^1.2.7", "ts-md5": "^1.2.7",
"typescript": "^4.1.3", "typescript": "^4.1.3",
"underscore":"^1.12.0", "underscore":"^1.12.0",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"winston": "^3.3.3" "winston": "^3.3.3",
"xmldom-ts": "^0.3.1"
}, },
"devDependencies": { "devDependencies": {
"@types/chai": "^4.2.14", "@types/chai": "^4.2.14",
@@ -34,11 +37,12 @@
"supertest": "^6.1.3", "supertest": "^6.1.3",
"ts-jest": "^26.4.4", "ts-jest": "^26.4.4",
"ts-mockito": "^2.6.1", "ts-mockito": "^2.6.1",
"ts-node": "^9.1.1" "ts-node": "^9.1.1",
"xpath-ts": "^1.3.13"
}, },
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"dev": "nodemon ./src/app.ts", "dev": "BONOB_PORT=4000 BONOB_WEB_ADDRESS=http://$(hostname):4000 nodemon ./src/app.ts",
"test": "jest", "test": "jest",
"client-test": "ts-node tests/bonob_client.ts" "client-test": "ts-node tests/bonob_client.ts"
} }

View File

@@ -1,16 +1,19 @@
import sonos, { bonobService } from "./sonos"; import sonos, { bonobService } from "./sonos";
import server from "./server"; import server from "./server";
import logger from "./logger"; import logger from "./logger";
import { Navidrome } from './music_service';
const PORT = process.env["BONOB_PORT"] || 4534;
const PORT = +(process.env["BONOB_PORT"] || 4534);
const WEB_ADDRESS = process.env["BONOB_WEB_ADDRESS"] || `http://localhost:${PORT}`; const WEB_ADDRESS = process.env["BONOB_WEB_ADDRESS"] || `http://localhost:${PORT}`;
const bonob = bonobService( const bonob = bonobService(
process.env["BONOB_SONOS_SERVICE_NAME"] || "bonob", process.env["BONOB_SONOS_SERVICE_NAME"] || "bonob",
Number(process.env["BONOS_SONOS_SERVICE_ID"] || "246"), Number(process.env["BONOS_SONOS_SERVICE_ID"] || "246"),
WEB_ADDRESS WEB_ADDRESS,
'AppLink'
); );
const app = server(sonos(process.env["BONOB_SONOS_SEED_HOST"]), bonob); const app = server(sonos(process.env["BONOB_SONOS_SEED_HOST"]), bonob, WEB_ADDRESS, new Navidrome());
app.listen(PORT, () => { app.listen(PORT, () => {
logger.info(`Listening on ${PORT} available @ ${WEB_ADDRESS}`); logger.info(`Listening on ${PORT} available @ ${WEB_ADDRESS}`);

20
src/link_codes.ts Normal file
View File

@@ -0,0 +1,20 @@
import { v4 as uuid } from 'uuid';
export interface LinkCodes {
mint(): string
clear(): any
count(): Number
}
export class InMemoryLinkCodes implements LinkCodes {
linkCodes: Record<string, string> = {}
mint() {
const linkCode = uuid();
this.linkCodes[linkCode] = ""
return linkCode
}
clear = () => { this.linkCodes = {} }
count = () => Object.keys(this.linkCodes).length
}

View File

@@ -6,7 +6,17 @@ const navidrome = process.env["BONOB_NAVIDROME_URL"];
const u = process.env["BONOB_USER"]; const u = process.env["BONOB_USER"];
const t = Md5.hashStr(`${process.env["BONOB_PASSWORD"]}${s}`); const t = Md5.hashStr(`${process.env["BONOB_PASSWORD"]}${s}`);
export class Navidrome { export type Credentials = { username: string, password: string }
export interface MusicService {
login(credentials: Credentials): boolean
}
export class Navidrome implements MusicService {
login(_: Credentials) {
return false
}
ping = (): Promise<boolean> => ping = (): Promise<boolean> =>
axios axios
.get( .get(
@@ -18,3 +28,6 @@ export class Navidrome {
return false; return false;
}); });
} }

View File

@@ -3,8 +3,17 @@ import * as Eta from "eta";
import { listen } from "soap"; import { listen } from "soap";
import { readFileSync } from "fs"; import { readFileSync } from "fs";
import path from "path"; import path from "path";
import morgan from "morgan";
import { Sonos, Service } from "./sonos"; import {
Sonos,
Service,
SOAP_PATH,
STRINGS_PATH,
PRESENTATION_MAP_PATH,
} from "./sonos";
import { LinkCodes, InMemoryLinkCodes } from './link_codes'
import { MusicService } from './music_service'
import logger from "./logger"; import logger from "./logger";
const WSDL_FILE = path.resolve( const WSDL_FILE = path.resolve(
@@ -12,9 +21,18 @@ const WSDL_FILE = path.resolve(
"Sonoswsdl-1.19.4-20190411.142401-3.wsdl" "Sonoswsdl-1.19.4-20190411.142401-3.wsdl"
); );
function server(sonos: Sonos, bonobService: Service): Express { function server(
sonos: Sonos,
bonobService: Service,
webAddress: string | "http://localhost:1234",
musicService: MusicService,
linkCodes: LinkCodes = new InMemoryLinkCodes()
): Express {
const app = express(); const app = express();
app.use(morgan("combined"));
app.use(express.urlencoded({ extended: false }));
app.use(express.static("./web/public")); app.use(express.static("./web/public"));
app.engine("eta", Eta.renderFile); app.engine("eta", Eta.renderFile);
@@ -44,18 +62,62 @@ function server(sonos: Sonos, bonobService: Service): Express {
}); });
}); });
app.get("/login", (req, res) => {
res.render("login", {
bonobService,
linkCode: req.query.linkCode
});
});
app.post("/login", (req, res) => {
const canLogIn = musicService.login({ username: req.body.username, password: req.body.password})
if(canLogIn)
res.send("ok")
else
res.send("boo")
});
app.get(STRINGS_PATH, (_, res) => {
res.type("application/xml").send(`<?xml version="1.0" encoding="utf-8" ?>
<stringtables xmlns="http://sonos.com/sonosapi">
<stringtable rev="1" xml:lang="en-US">
<string stringId="AppLinkMessage">Linking sonos with bonob</string>
</stringtable>
</stringtables>
`);
});
app.get(PRESENTATION_MAP_PATH, (_, res) => {
res.send("");
});
const sonosService = { const sonosService = {
Sonos: { Sonos: {
SonosSoap: { SonosSoap: {
getAppLink: () => {
const linkCode = linkCodes.mint();
return {
getAppLinkResult: {
authorizeAccount: {
appUrlStringId: 'AppLinkMessage',
deviceLink: {
regUrl: `${webAddress}/login?linkCode=${linkCode}`,
linkCode: linkCode,
showLinkCode: false,
},
},
}
};
},
getSessionId: ({ getSessionId: ({
username username,
}: { }: {
username: string; username: string;
password: string; password: string;
}) => { }) => {
return Promise.resolve({ return Promise.resolve({
username, username,
sessionId: '123' sessionId: "123",
}); });
}, },
}, },
@@ -64,7 +126,7 @@ function server(sonos: Sonos, bonobService: Service): Express {
const x = listen( const x = listen(
app, app,
"/ws", SOAP_PATH,
sonosService, sonosService,
readFileSync(WSDL_FILE, "utf8") readFileSync(WSDL_FILE, "utf8")
); );
@@ -72,16 +134,16 @@ function server(sonos: Sonos, bonobService: Service): Express {
x.log = (type, data) => { x.log = (type, data) => {
switch (type) { switch (type) {
case "info": case "info":
logger.info({ data }); logger.info({ level:"info", data });
break; break;
case "warn": case "warn":
logger.warn({ data }); logger.warn({ level:"warn", data });
break; break;
case "error": case "error":
logger.error({ data }); logger.error({ level:"error", data });
break; break;
default: default:
logger.debug({ data }); logger.debug({ level:"debug", data });
} }
}; };

2
src/smapi.ts Normal file
View File

@@ -0,0 +1,2 @@
export type GetAppLinkResult = { getAppLinkResult: { authorizeAccount: { appUrlStringId: string, deviceLink: { regUrl: string, linkCode:string,showLinkCode:boolean }} } }

View File

@@ -4,6 +4,11 @@ import { parse } from "node-html-parser";
import { MusicService } from "@svrooij/sonos/lib/services"; import { MusicService } from "@svrooij/sonos/lib/services";
import { head } from "underscore"; import { head } from "underscore";
import logger from "./logger"; import logger from "./logger";
import STRINGS from './strings';
export const SOAP_PATH = "/ws/sonos";
export const STRINGS_PATH = "/sonos/strings.xml";
export const PRESENTATION_MAP_PATH = "/sonos/presentationMap.xml";
export type Device = { export type Device = {
name: string; name: string;
@@ -20,7 +25,7 @@ export type Service = {
strings: { uri?: string; version?: string }; strings: { uri?: string; version?: string };
presentation: { uri?: string; version?: string }; presentation: { uri?: string; version?: string };
pollInterval?: number; pollInterval?: number;
authType: string; authType: 'Anonymous' | 'AppLink' | 'DeviceLink' | 'UserId';
}; };
const stripTailingSlash = (url: string) => const stripTailingSlash = (url: string) =>
@@ -29,22 +34,23 @@ const stripTailingSlash = (url: string) =>
export const bonobService = ( export const bonobService = (
name: string, name: string,
sid: number, sid: number,
bonobRoot: string bonobRoot: string,
authType: 'Anonymous' | 'AppLink' | 'DeviceLink' | 'UserId' = 'AppLink'
): Service => ({ ): Service => ({
name, name,
sid, sid,
uri: `${stripTailingSlash(bonobRoot)}/ws/sonos`, uri: `${stripTailingSlash(bonobRoot)}${SOAP_PATH}`,
secureUri: `${stripTailingSlash(bonobRoot)}/ws/sonos`, secureUri: `${stripTailingSlash(bonobRoot)}${SOAP_PATH}`,
strings: { strings: {
uri: `${stripTailingSlash(bonobRoot)}/sonos/strings.xml`, uri: `${stripTailingSlash(bonobRoot)}${STRINGS_PATH}`,
version: "1", version: STRINGS.version,
}, },
presentation: { presentation: {
uri: `${stripTailingSlash(bonobRoot)}/sonos/presentationMap.xml`, uri: `${stripTailingSlash(bonobRoot)}${PRESENTATION_MAP_PATH}`,
version: "1", version: "1",
}, },
pollInterval: 1200, pollInterval: 1200,
authType: "Anonymous", authType,
}); });
export interface Sonos { export interface Sonos {
@@ -119,7 +125,6 @@ export function autoDiscoverySonos(sonosSeedHost?: string): Sonos {
return setupDiscovery(manager, sonosSeedHost) return setupDiscovery(manager, sonosSeedHost)
.then((success) => { .then((success) => {
if (success) { if (success) {
console.log("had success");
return manager.Devices; return manager.Devices;
} else { } else {
logger.warn("Didn't find any sonos devices!"); logger.warn("Didn't find any sonos devices!");

10
src/strings.ts Normal file
View File

@@ -0,0 +1,10 @@
const STRINGS = {
version: "1",
values: {
"foo": "bar"
}
}
export default STRINGS;

View File

@@ -5,16 +5,19 @@ import sonos, { bonobService } from "../src/sonos";
import server from "../src/server"; import server from "../src/server";
import logger from "../src/logger"; import logger from "../src/logger";
import { InMemoryMusicService } from "builders";
const bonob = bonobService("bonob-test", 247, "http://localhost:1234"); const WEB_ADDRESS = "http://localhost:1234"
const app = server(sonos("disabled"), bonob);
const bonob = bonobService("bonob-test", 247, WEB_ADDRESS, 'Anonymous');
const app = server(sonos("disabled"), bonob, WEB_ADDRESS, new InMemoryMusicService());
getPort().then((port) => { getPort().then((port) => {
logger.debug(`Starting on port ${port}`); logger.debug(`Starting on port ${port}`);
app.listen(port); app.listen(port);
createClientAsync(`http://localhost:${port}/ws?wsdl`, { createClientAsync(`${bonob.uri}?wsdl`, {
endpoint: `http://localhost:${port}/ws`, endpoint: bonob.uri,
}).then((client) => { }).then((client) => {
client client
.getSessionIdAsync( .getSessionIdAsync(

View File

@@ -1,22 +1,23 @@
import { SonosDevice } from "@svrooij/sonos/lib"; import { SonosDevice } from "@svrooij/sonos/lib";
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from "uuid";
import { MusicService, Credentials } from "../src/music_service";
import { Service, Device } from "../src/sonos"; import { Service, Device } from "../src/sonos";
const randomInt = (max: number) => Math.floor(Math.random() * max) const randomInt = (max: number) => Math.floor(Math.random() * max);
const randomIpAddress = () => `127.0.${randomInt(255)}.${randomInt(255)}` const randomIpAddress = () => `127.0.${randomInt(255)}.${randomInt(255)}`;
export const aService = (fields: Partial<Service> = {}): Service => ({ export const aService = (fields: Partial<Service> = {}): Service => ({
name: `Test Music Service ${uuid()}`, name: `Test Music Service ${uuid()}`,
sid: randomInt(500), sid: randomInt(500),
uri: "https://sonos.testmusic.com/", uri: "https://sonos-test.example.com/",
secureUri: "https://sonos.testmusic.com/", secureUri: "https://sonos-test.example.com/",
strings: { strings: {
uri: "https://sonos.testmusic.com/strings.xml", uri: "https://sonos-test.example.com/strings.xml",
version: "22", version: "22",
}, },
presentation: { presentation: {
uri: "https://sonos.testmusic.com/presentation.xml", uri: "https://sonos-test.example.com/presentation.xml",
version: "33", version: "33",
}, },
pollInterval: 1200, pollInterval: 1200,
@@ -35,9 +36,7 @@ export function aDevice(fields: Partial<Device> = {}): Device {
}; };
} }
export function aSonosDevice( export function aSonosDevice(fields: Partial<SonosDevice> = {}): SonosDevice {
fields: Partial<SonosDevice> = {}
): SonosDevice {
return { return {
Name: `device-${uuid()}`, Name: `device-${uuid()}`,
GroupName: `group-${uuid()}`, GroupName: `group-${uuid()}`,
@@ -46,3 +45,33 @@ export function aSonosDevice(
...fields, ...fields,
} as SonosDevice; } as SonosDevice;
} }
export function getAppLinkMessage() {
return {
householdId: "",
hardware: "",
osVersion: "",
sonosAppName: "",
callbackPath: "",
};
}
export class InMemoryMusicService implements MusicService {
users: Record<string, string> = {};
login({ username, password }: Credentials) {
return username != undefined && password != undefined && this.users[username] == password;
}
hasUser(credentials: Credentials) {
this.users[credentials.username] = credentials.password;
}
hasNoUsers() {
this.users = {};
}
clear() {
this.users = {};
}
}

View File

@@ -2,11 +2,11 @@ import request from "supertest";
import makeServer from "../src/server"; import makeServer from "../src/server";
import { SONOS_DISABLED, Sonos, Device } from "../src/sonos"; import { SONOS_DISABLED, Sonos, Device } from "../src/sonos";
import { aDevice, aService } from './builders'; import { aDevice, aService, InMemoryMusicService } from './builders';
describe("index", () => { describe("index", () => {
describe("when sonos integration is disabled", () => { describe("when sonos integration is disabled", () => {
const server = makeServer(SONOS_DISABLED, aService()); const server = makeServer(SONOS_DISABLED, aService(), 'http://localhost:1234', new InMemoryMusicService());
describe("devices list", () => { describe("devices list", () => {
it("should be empty", async () => { it("should be empty", async () => {
@@ -58,7 +58,7 @@ describe("index", () => {
register: () => Promise.resolve(false), register: () => Promise.resolve(false),
}; };
const server = makeServer(fakeSonos, missingBonobService); const server = makeServer(fakeSonos, missingBonobService, 'http://localhost:1234', new InMemoryMusicService());
describe("devices list", () => { describe("devices list", () => {
it("should contain the devices returned from sonos", async () => { it("should contain the devices returned from sonos", async () => {
@@ -108,7 +108,7 @@ describe("index", () => {
register: () => Promise.resolve(false), register: () => Promise.resolve(false),
}; };
const server = makeServer(fakeSonos, bonobService); const server = makeServer(fakeSonos, bonobService, 'http://localhost:1234', new InMemoryMusicService());
describe("registration status", () => { describe("registration status", () => {
it("should be registered", async () => { it("should be registered", async () => {

124
tests/scenarios.test.ts Normal file
View File

@@ -0,0 +1,124 @@
import { createClientAsync } from "soap";
import { Express } from "express";
import request from "supertest";
import { GetAppLinkResult } from "../src/smapi";
import { InMemoryMusicService, getAppLinkMessage } from "./builders";
import { InMemoryLinkCodes } from "../src/link_codes";
import { Credentials } from "../src/music_service";
import makeServer from "../src/server";
import { Service, bonobService, SONOS_DISABLED } from "../src/sonos";
import supersoap from "./supersoap";
class SonosDriver {
server: Express;
rootUrl: string;
service: Service;
constructor(server: Express, rootUrl: string, service: Service) {
this.server = server;
this.rootUrl = rootUrl;
this.service = service;
}
stripServiceRoot = (url: string) => url.replace(this.rootUrl, "");
async addService() {
expect(this.service.authType).toEqual("AppLink");
await request(this.server)
.get(this.stripServiceRoot(this.service.strings.uri!))
.expect(200);
await request(this.server)
.get(this.stripServiceRoot(this.service.presentation.uri!))
.expect(200);
return createClientAsync(`${this.service.uri}?wsdl`, {
endpoint: this.service.uri,
httpClient: supersoap(this.server, this.rootUrl),
}).then((client) =>
client
.getAppLinkAsync(getAppLinkMessage())
.then(
([result]: [GetAppLinkResult]) =>
result.getAppLinkResult.authorizeAccount.deviceLink
)
.then(({ regUrl, linkCode }: { regUrl: string; linkCode: string }) => ({
login: async ({ username, password }: Credentials) => {
await request(this.server).get(this.stripServiceRoot(regUrl)).expect(200);
return request(this.server)
.post(this.stripServiceRoot(regUrl))
.type("form")
.send({ username, password, linkCode })
.expect(200)
.then(response => ({
expectSuccess: () => {
expect(response.text).toContain("ok")
},
expectFailure: () => {
expect(response.text).toContain("boo")
},
}));
},
}))
);
}
}
describe("scenarios", () => {
const bonobUrl = "http://localhost:1234";
const bonob = bonobService("bonob", 123, bonobUrl);
const musicService = new InMemoryMusicService();
const linkCodes = new InMemoryLinkCodes();
const server = makeServer(
SONOS_DISABLED,
bonob,
bonobUrl,
musicService,
linkCodes
);
const sonosDriver = new SonosDriver(server, bonobUrl, bonob);
beforeEach(() => {
musicService.clear();
linkCodes.clear();
});
describe("adding the service", () => {
describe("when the user exists within the music service", () => {
const username = "validuser";
const password = "validpassword";
it("should successfully sign up", async () => {
musicService.hasUser({ username, password });
await sonosDriver
.addService()
.then((it) => it.login({ username, password }))
.then((it) => it.expectSuccess());
expect(linkCodes.count()).toEqual(1);
});
});
describe("when the user doesnt exists within the music service", () => {
const username = "invaliduser";
const password = "invalidpassword";
it("should fail to sign up", async () => {
musicService.hasNoUsers();
await sonosDriver
.addService()
.then((it) => it.login({ username, password }))
.then((it) => it.expectFailure());
expect(linkCodes.count()).toEqual(1);
});
});
});
});

View File

@@ -1,4 +1,5 @@
global.console = { global.console = {
// log: console.log,
log: jest.fn(), // console.log are ignored in tests log: jest.fn(), // console.log are ignored in tests
// Keep native behaviour for other methods, use those to print out things in your own tests, not `console.log` // Keep native behaviour for other methods, use those to print out things in your own tests, not `console.log`

27
tests/smapi.test.ts Normal file
View File

@@ -0,0 +1,27 @@
import request from "supertest";
import { DOMParserImpl } from 'xmldom-ts';
import * as xpath from 'xpath-ts';
import makeServer from "../src/server";
import { SONOS_DISABLED, STRINGS_PATH } from "../src/sonos";
import { aService, InMemoryMusicService } from './builders';
const parseXML = (value: string) => new DOMParserImpl().parseFromString(value);
const select = xpath.useNamespaces({"sonos": "http://sonos.com/sonosapi"})
describe('strings.xml', () => {
const server = makeServer(SONOS_DISABLED, aService(), 'http://localhost:1234', new InMemoryMusicService());
it("should return xml for the strings", async () => {
const res = await request(server).get(STRINGS_PATH).send();
expect(res.status).toEqual(200);
const xml = parseXML(res.text);
const x = select("//sonos:string[@stringId='AppLinkMessage']/text()", xml) as Node[]
expect(x.length).toEqual(1)
expect(x[0]!.nodeValue).toEqual("Linking sonos with bonob")
});
});

View File

@@ -122,7 +122,7 @@ describe("sonos", () => {
version: "1", version: "1",
}, },
pollInterval: 1200, pollInterval: 1200,
authType: "Anonymous", authType: "AppLink",
}); });
}); });
}); });
@@ -145,7 +145,30 @@ describe("sonos", () => {
version: "1", version: "1",
}, },
pollInterval: 1200, pollInterval: 1200,
authType: "Anonymous", authType: "AppLink",
});
});
});
describe("when authType is specified", () => {
it("should return a valid bonob service", () => {
expect(
bonobService("some-bonob", 876, "http://bonob.example.com", 'DeviceLink')
).toEqual({
name: "some-bonob",
sid: 876,
uri: `http://bonob.example.com/ws/sonos`,
secureUri: `http://bonob.example.com/ws/sonos`,
strings: {
uri: `http://bonob.example.com/sonos/strings.xml`,
version: "1",
},
presentation: {
uri: `http://bonob.example.com/sonos/presentationMap.xml`,
version: "1",
},
pollInterval: 1200,
authType: "DeviceLink",
}); });
}); });
}); });
@@ -166,7 +189,7 @@ describe("sonos", () => {
version: "27", version: "27",
}, },
pollInterval: 5600, pollInterval: 5600,
authType: "SpecialAuth", authType: "UserId",
}; };
expect(asCustomdForm(csrfToken, service)).toEqual({ expect(asCustomdForm(csrfToken, service)).toEqual({
@@ -176,7 +199,7 @@ describe("sonos", () => {
uri: "http://aa.example.com", uri: "http://aa.example.com",
secureUri: "https://aa.example.com", secureUri: "https://aa.example.com",
pollInterval: "5600", pollInterval: "5600",
authType: "SpecialAuth", authType: "UserId",
stringsVersion: "26", stringsVersion: "26",
stringsUri: "http://strings.example.com", stringsUri: "http://strings.example.com",
presentationMapVersion: "27", presentationMapVersion: "27",

25
tests/supersoap.ts Normal file
View File

@@ -0,0 +1,25 @@
import { Express } from "express";
import request from "supertest";
function supersoap(server: Express, rootUrl: string) {
return {
request: (
rurl: string,
data: any,
callback: (error: any, res?: any, body?: any) => any,
exheaders?: any
) => {
const withoutHost = rurl.replace(rootUrl, "");
const req =
data == null
? request(server).get(withoutHost).send()
: request(server).post(withoutHost).send(data);
req
.set(exheaders || {})
.then((response) => callback(null, response, response.text))
.catch(callback);
},
}
}
export default supersoap

View File

@@ -1,38 +1,22 @@
import request from "supertest";
import makeServer from "../src/server"; import makeServer from "../src/server";
import { SONOS_DISABLED } from "../src/sonos"; import { SONOS_DISABLED, SOAP_PATH } from "../src/sonos";
import { aService } from "./builders"; import { aService, InMemoryMusicService } from "./builders";
import supersoap from './supersoap';
import { createClientAsync } from "soap"; import { createClientAsync } from "soap";
describe("ws", () => { describe("ws", () => {
describe("can call getSessionId", () => { describe("can call getSessionId", () => {
it("should do something", async () => { it("should do something", async () => {
const server = makeServer(SONOS_DISABLED, aService()); const WEB_ADDRESS = 'http://localhost:7653'
const server = makeServer(SONOS_DISABLED, aService(), WEB_ADDRESS, new InMemoryMusicService());
const { username, sessionId } = await createClientAsync( const { username, sessionId } = await createClientAsync(
`http://localhost/ws?wsdl`, `${WEB_ADDRESS}${SOAP_PATH}?wsdl`,
{ {
endpoint: `http://localhost/ws`, endpoint: `${WEB_ADDRESS}${SOAP_PATH}`,
httpClient: { httpClient: supersoap(server, WEB_ADDRESS),
request: (
rurl: string,
data: any,
callback: (error: any, res?: any, body?: any) => any,
exheaders?: any
) => {
const withoutHost = rurl.replace("http://localhost", "");
const req =
data == null
? request(server).get(withoutHost).send()
: request(server).post(withoutHost).send(data);
req
.set(exheaders || {})
.then((response) => callback(null, response, response.text))
.catch(callback);
},
},
} }
).then((client) => ).then((client) =>
client client

View File

@@ -1,7 +1,7 @@
<% layout('./layout') %> <% layout('./layout') %>
<div id="content"> <div id="content">
<h1>bonob</h1> <h1>bonob service</h1>
<h2><%= it.bonobService.name %> (<%= it.bonobService.sid %>) <h2><%= it.bonobService.name %> (<%= it.bonobService.sid %>)
<h3>Expected config</h3> <h3>Expected config</h3>
<div><%= JSON.stringify(it.bonobService) %></div> <div><%= JSON.stringify(it.bonobService) %></div>

11
web/views/login.eta Normal file
View File

@@ -0,0 +1,11 @@
<% layout('./layout', { title: "Login" }) %>
<div id="content">
<h1>Log in to <%= it.bonobService.name %></h1>
<form action="/login" method="POST">
<label for="username">Username:</label><input type="text" id="username" name="username"><br>
<label for="password">Password:</label><input type="text" id="password" name="password"><br>
<input type="hidden" name="linkCode" value="<%= it.linkCode %>">
<input type="submit" value="Login">
</form>
</div>

407
yarn.lock
View File

@@ -2,26 +2,26 @@
# yarn lockfile v1 # yarn lockfile v1
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.11": "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13":
version "7.12.11" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658"
integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==
dependencies: dependencies:
"@babel/highlight" "^7.10.4" "@babel/highlight" "^7.12.13"
"@babel/core@^7.1.0", "@babel/core@^7.7.5": "@babel/core@^7.1.0", "@babel/core@^7.7.5":
version "7.12.10" version "7.12.16"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.10.tgz#b79a2e1b9f70ed3d84bbfb6d8c4ef825f606bccd" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.16.tgz#8c6ba456b23b680a6493ddcfcd9d3c3ad51cab7c"
integrity sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w== integrity sha512-t/hHIB504wWceOeaOoONOhu+gX+hpjfeN6YRBT209X/4sibZQfSF1I0HFRRlBe97UZZosGx5XwUg1ZgNbelmNw==
dependencies: dependencies:
"@babel/code-frame" "^7.10.4" "@babel/code-frame" "^7.12.13"
"@babel/generator" "^7.12.10" "@babel/generator" "^7.12.15"
"@babel/helper-module-transforms" "^7.12.1" "@babel/helper-module-transforms" "^7.12.13"
"@babel/helpers" "^7.12.5" "@babel/helpers" "^7.12.13"
"@babel/parser" "^7.12.10" "@babel/parser" "^7.12.16"
"@babel/template" "^7.12.7" "@babel/template" "^7.12.13"
"@babel/traverse" "^7.12.10" "@babel/traverse" "^7.12.13"
"@babel/types" "^7.12.10" "@babel/types" "^7.12.13"
convert-source-map "^1.7.0" convert-source-map "^1.7.0"
debug "^4.1.0" debug "^4.1.0"
gensync "^1.0.0-beta.1" gensync "^1.0.0-beta.1"
@@ -30,123 +30,123 @@
semver "^5.4.1" semver "^5.4.1"
source-map "^0.5.0" source-map "^0.5.0"
"@babel/generator@^7.12.10", "@babel/generator@^7.12.11": "@babel/generator@^7.12.13", "@babel/generator@^7.12.15":
version "7.12.11" version "7.12.15"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.11.tgz#98a7df7b8c358c9a37ab07a24056853016aba3af" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.15.tgz#4617b5d0b25cc572474cc1aafee1edeaf9b5368f"
integrity sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA== integrity sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==
dependencies: dependencies:
"@babel/types" "^7.12.11" "@babel/types" "^7.12.13"
jsesc "^2.5.1" jsesc "^2.5.1"
source-map "^0.5.0" source-map "^0.5.0"
"@babel/helper-function-name@^7.12.11": "@babel/helper-function-name@^7.12.13":
version "7.12.11" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz#1fd7738aee5dcf53c3ecff24f1da9c511ec47b42" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a"
integrity sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA== integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==
dependencies: dependencies:
"@babel/helper-get-function-arity" "^7.12.10" "@babel/helper-get-function-arity" "^7.12.13"
"@babel/template" "^7.12.7" "@babel/template" "^7.12.13"
"@babel/types" "^7.12.11" "@babel/types" "^7.12.13"
"@babel/helper-get-function-arity@^7.12.10": "@babel/helper-get-function-arity@^7.12.13":
version "7.12.10" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz#b158817a3165b5faa2047825dfa61970ddcc16cf" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583"
integrity sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag== integrity sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==
dependencies: dependencies:
"@babel/types" "^7.12.10" "@babel/types" "^7.12.13"
"@babel/helper-member-expression-to-functions@^7.12.7": "@babel/helper-member-expression-to-functions@^7.12.13":
version "7.12.7" version "7.12.16"
resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz#aa77bd0396ec8114e5e30787efa78599d874a855" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz#41e0916b99f8d5f43da4f05d85f4930fa3d62b22"
integrity sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw== integrity sha512-zYoZC1uvebBFmj1wFAlXwt35JLEgecefATtKp20xalwEK8vHAixLBXTGxNrVGEmTT+gzOThUgr8UEdgtalc1BQ==
dependencies: dependencies:
"@babel/types" "^7.12.7" "@babel/types" "^7.12.13"
"@babel/helper-module-imports@^7.12.1": "@babel/helper-module-imports@^7.12.13":
version "7.12.5" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz#1bfc0229f794988f76ed0a4d4e90860850b54dfb" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz#ec67e4404f41750463e455cc3203f6a32e93fcb0"
integrity sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA== integrity sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==
dependencies: dependencies:
"@babel/types" "^7.12.5" "@babel/types" "^7.12.13"
"@babel/helper-module-transforms@^7.12.1": "@babel/helper-module-transforms@^7.12.13":
version "7.12.1" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz#7954fec71f5b32c48e4b303b437c34453fd7247c" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz#01afb052dcad2044289b7b20beb3fa8bd0265bea"
integrity sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w== integrity sha512-acKF7EjqOR67ASIlDTupwkKM1eUisNAjaSduo5Cz+793ikfnpe7p4Q7B7EWU2PCoSTPWsQkR7hRUWEIZPiVLGA==
dependencies: dependencies:
"@babel/helper-module-imports" "^7.12.1" "@babel/helper-module-imports" "^7.12.13"
"@babel/helper-replace-supers" "^7.12.1" "@babel/helper-replace-supers" "^7.12.13"
"@babel/helper-simple-access" "^7.12.1" "@babel/helper-simple-access" "^7.12.13"
"@babel/helper-split-export-declaration" "^7.11.0" "@babel/helper-split-export-declaration" "^7.12.13"
"@babel/helper-validator-identifier" "^7.10.4" "@babel/helper-validator-identifier" "^7.12.11"
"@babel/template" "^7.10.4" "@babel/template" "^7.12.13"
"@babel/traverse" "^7.12.1" "@babel/traverse" "^7.12.13"
"@babel/types" "^7.12.1" "@babel/types" "^7.12.13"
lodash "^4.17.19" lodash "^4.17.19"
"@babel/helper-optimise-call-expression@^7.12.10": "@babel/helper-optimise-call-expression@^7.12.13":
version "7.12.10" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz#94ca4e306ee11a7dd6e9f42823e2ac6b49881e2d" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea"
integrity sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ== integrity sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==
dependencies: dependencies:
"@babel/types" "^7.12.10" "@babel/types" "^7.12.13"
"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0": "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.8.0":
version "7.10.4" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.12.13.tgz#174254d0f2424d8aefb4dd48057511247b0a9eeb"
integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== integrity sha512-C+10MXCXJLiR6IeG9+Wiejt9jmtFpxUc3MQqCmPY8hfCjyUGl9kT+B2okzEZrtykiwrc4dbCPdDoz0A/HQbDaA==
"@babel/helper-replace-supers@^7.12.1": "@babel/helper-replace-supers@^7.12.13":
version "7.12.11" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz#ea511658fc66c7908f923106dd88e08d1997d60d" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz#00ec4fb6862546bd3d0aff9aac56074277173121"
integrity sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA== integrity sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg==
dependencies: dependencies:
"@babel/helper-member-expression-to-functions" "^7.12.7" "@babel/helper-member-expression-to-functions" "^7.12.13"
"@babel/helper-optimise-call-expression" "^7.12.10" "@babel/helper-optimise-call-expression" "^7.12.13"
"@babel/traverse" "^7.12.10" "@babel/traverse" "^7.12.13"
"@babel/types" "^7.12.11" "@babel/types" "^7.12.13"
"@babel/helper-simple-access@^7.12.1": "@babel/helper-simple-access@^7.12.13":
version "7.12.1" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz#32427e5aa61547d38eb1e6eaf5fd1426fdad9136" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz#8478bcc5cacf6aa1672b251c1d2dde5ccd61a6c4"
integrity sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA== integrity sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA==
dependencies: dependencies:
"@babel/types" "^7.12.1" "@babel/types" "^7.12.13"
"@babel/helper-split-export-declaration@^7.11.0", "@babel/helper-split-export-declaration@^7.12.11": "@babel/helper-split-export-declaration@^7.12.13":
version "7.12.11" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz#1b4cc424458643c47d37022223da33d76ea4603a" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05"
integrity sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g== integrity sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==
dependencies: dependencies:
"@babel/types" "^7.12.11" "@babel/types" "^7.12.13"
"@babel/helper-validator-identifier@^7.10.4", "@babel/helper-validator-identifier@^7.12.11": "@babel/helper-validator-identifier@^7.12.11":
version "7.12.11" version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed"
integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==
"@babel/helpers@^7.12.5": "@babel/helpers@^7.12.13":
version "7.12.5" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.5.tgz#1a1ba4a768d9b58310eda516c449913fe647116e" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.13.tgz#3c75e993632e4dadc0274eae219c73eb7645ba47"
integrity sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA== integrity sha512-oohVzLRZ3GQEk4Cjhfs9YkJA4TdIDTObdBEZGrd6F/T0GPSnuV6l22eMcxlvcvzVIPH3VTtxbseudM1zIE+rPQ==
dependencies: dependencies:
"@babel/template" "^7.10.4" "@babel/template" "^7.12.13"
"@babel/traverse" "^7.12.5" "@babel/traverse" "^7.12.13"
"@babel/types" "^7.12.5" "@babel/types" "^7.12.13"
"@babel/highlight@^7.10.4": "@babel/highlight@^7.12.13":
version "7.10.4" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.12.13.tgz#8ab538393e00370b26271b01fa08f7f27f2e795c"
integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== integrity sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==
dependencies: dependencies:
"@babel/helper-validator-identifier" "^7.10.4" "@babel/helper-validator-identifier" "^7.12.11"
chalk "^2.0.0" chalk "^2.0.0"
js-tokens "^4.0.0" js-tokens "^4.0.0"
"@babel/parser@^7.1.0", "@babel/parser@^7.12.10", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7": "@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.12.16":
version "7.12.11" version "7.12.16"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.11.tgz#9ce3595bcd74bc5c466905e86c535b8b25011e79" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.16.tgz#cc31257419d2c3189d394081635703f549fc1ed4"
integrity sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg== integrity sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==
"@babel/plugin-syntax-async-generators@^7.8.4": "@babel/plugin-syntax-async-generators@^7.8.4":
version "7.8.4" version "7.8.4"
@@ -163,11 +163,11 @@
"@babel/helper-plugin-utils" "^7.8.0" "@babel/helper-plugin-utils" "^7.8.0"
"@babel/plugin-syntax-class-properties@^7.8.3": "@babel/plugin-syntax-class-properties@^7.8.3":
version "7.12.1" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz#bcb297c5366e79bebadef509549cd93b04f19978" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10"
integrity sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA== integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.10.4" "@babel/helper-plugin-utils" "^7.12.13"
"@babel/plugin-syntax-import-meta@^7.8.3": "@babel/plugin-syntax-import-meta@^7.8.3":
version "7.10.4" version "7.10.4"
@@ -226,40 +226,40 @@
"@babel/helper-plugin-utils" "^7.8.0" "@babel/helper-plugin-utils" "^7.8.0"
"@babel/plugin-syntax-top-level-await@^7.8.3": "@babel/plugin-syntax-top-level-await@^7.8.3":
version "7.12.1" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz#dd6c0b357ac1bb142d98537450a319625d13d2a0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz#c5f0fa6e249f5b739727f923540cf7a806130178"
integrity sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A== integrity sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.10.4" "@babel/helper-plugin-utils" "^7.12.13"
"@babel/template@^7.10.4", "@babel/template@^7.12.7", "@babel/template@^7.3.3": "@babel/template@^7.12.13", "@babel/template@^7.3.3":
version "7.12.7" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.7.tgz#c817233696018e39fbb6c491d2fb684e05ed43bc" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327"
integrity sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow== integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==
dependencies: dependencies:
"@babel/code-frame" "^7.10.4" "@babel/code-frame" "^7.12.13"
"@babel/parser" "^7.12.7" "@babel/parser" "^7.12.13"
"@babel/types" "^7.12.7" "@babel/types" "^7.12.13"
"@babel/traverse@^7.1.0", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5": "@babel/traverse@^7.1.0", "@babel/traverse@^7.12.13":
version "7.12.12" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.12.tgz#d0cd87892704edd8da002d674bc811ce64743376" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.13.tgz#689f0e4b4c08587ad26622832632735fb8c4e0c0"
integrity sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w== integrity sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==
dependencies: dependencies:
"@babel/code-frame" "^7.12.11" "@babel/code-frame" "^7.12.13"
"@babel/generator" "^7.12.11" "@babel/generator" "^7.12.13"
"@babel/helper-function-name" "^7.12.11" "@babel/helper-function-name" "^7.12.13"
"@babel/helper-split-export-declaration" "^7.12.11" "@babel/helper-split-export-declaration" "^7.12.13"
"@babel/parser" "^7.12.11" "@babel/parser" "^7.12.13"
"@babel/types" "^7.12.12" "@babel/types" "^7.12.13"
debug "^4.1.0" debug "^4.1.0"
globals "^11.1.0" globals "^11.1.0"
lodash "^4.17.19" lodash "^4.17.19"
"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.11", "@babel/types@^7.12.12", "@babel/types@^7.12.5", "@babel/types@^7.12.7", "@babel/types@^7.3.0", "@babel/types@^7.3.3": "@babel/types@^7.0.0", "@babel/types@^7.12.13", "@babel/types@^7.3.0", "@babel/types@^7.3.3":
version "7.12.12" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.12.tgz#4608a6ec313abbd87afa55004d373ad04a96c299" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.13.tgz#8be1aa8f2c876da11a9cf650c0ecf656913ad611"
integrity sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ== integrity sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==
dependencies: dependencies:
"@babel/helper-validator-identifier" "^7.12.11" "@babel/helper-validator-identifier" "^7.12.11"
lodash "^4.17.19" lodash "^4.17.19"
@@ -299,9 +299,9 @@
resolve-from "^5.0.0" resolve-from "^5.0.0"
"@istanbuljs/schema@^0.1.2": "@istanbuljs/schema@^0.1.2":
version "0.1.2" version "0.1.3"
resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98"
integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==
"@jest/console@^26.6.2": "@jest/console@^26.6.2":
version "26.6.2" version "26.6.2"
@@ -554,9 +554,9 @@
"@types/node" "*" "@types/node" "*"
"@types/chai@^4.2.14": "@types/chai@^4.2.14":
version "4.2.14" version "4.2.15"
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.14.tgz#44d2dd0b5de6185089375d976b4ec5caf6861193" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.15.tgz#b7a6d263c2cecf44b6de9a051cf496249b154553"
integrity sha512-G+ITQPXkwTrslfG5L/BksmbLUA0M1iybEsmCWPqzSxsRRhJZimBKJkoMi8fr/CPygPTj4zO5pJH7I2/cm9M7SQ== integrity sha512-rYff6FI+ZTKAPkJUoyz7Udq3GaoDZnxYDEvdEdFZASiA7PoErltHezDishqQiSDWrGxvxmplH304jyzQmjp0AQ==
"@types/connect@*": "@types/connect@*":
version "3.4.34" version "3.4.34"
@@ -590,9 +590,9 @@
"@types/serve-static" "*" "@types/serve-static" "*"
"@types/graceful-fs@^4.1.2": "@types/graceful-fs@^4.1.2":
version "4.1.4" version "4.1.5"
resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.4.tgz#4ff9f641a7c6d1a3508ff88bc3141b152772e753" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15"
integrity sha512-mWA/4zFQhfvOA8zWkXobwJvBD7vzcxgrOQ0J5CH1votGqdq9m7+FwtGaqyCZqC3NyyBkc9z4m+iry4LlqcMWJg== integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
@@ -633,10 +633,17 @@
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.0.tgz#3eb56d13a1de1d347ecb1957c6860c911704bc44" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.0.tgz#3eb56d13a1de1d347ecb1957c6860c911704bc44"
integrity sha512-/Sge3BymXo4lKc31C8OINJgXLaw+7vL1/L1pGiBNpGrBiT8FQiaFpSYV0uhTaG4y78vcMBTMFsWaHDvuD+xGzQ== integrity sha512-/Sge3BymXo4lKc31C8OINJgXLaw+7vL1/L1pGiBNpGrBiT8FQiaFpSYV0uhTaG4y78vcMBTMFsWaHDvuD+xGzQ==
"@types/morgan@^1.9.2":
version "1.9.2"
resolved "https://registry.yarnpkg.com/@types/morgan/-/morgan-1.9.2.tgz#450f958a4d3fb0694a3ba012b09c8106f9a2885e"
integrity sha512-edtGMEdit146JwwIeyQeHHg9yID4WSolQPxpEorHmN3KuytuCHyn2ELNr5Uxy8SerniFbbkmgKMrGM933am5BQ==
dependencies:
"@types/node" "*"
"@types/node@*", "@types/node@^14.14.22": "@types/node@*", "@types/node@^14.14.22":
version "14.14.22" version "14.14.28"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.22.tgz#0d29f382472c4ccf3bd96ff0ce47daf5b7b84b18" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.28.tgz#cade4b64f8438f588951a6b35843ce536853f25b"
integrity sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw== integrity sha512-lg55ArB+ZiHHbBBttLpzD07akz0QPrZgUODNakeC09i62dnrywr9mFErHuaPlB6I7z+sEbK+IYmplahvplCj2g==
"@types/normalize-package-data@^2.4.0": "@types/normalize-package-data@^2.4.0":
version "2.4.0" version "2.4.0"
@@ -644,9 +651,9 @@
integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==
"@types/prettier@^2.0.0": "@types/prettier@^2.0.0":
version "2.1.6" version "2.2.1"
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.1.6.tgz#f4b1efa784e8db479cdb8b14403e2144b1e9ff03" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.2.1.tgz#374e31645d58cb18a07b3ecd8e9dede4deb2cccd"
integrity sha512-6gOkRe7OIioWAXfnO/2lFiv+SJichKVSys1mSsgyrYHSEjk8Ctv4tSR/Odvnu+HWlH2C8j53dahU03XmQdd5fA== integrity sha512-DxZZbyMAM9GWEzXL+BMZROWz9oo6A9EilwwOMET2UVu2uZTqMWS5S69KVtuVKaRjCUpcrOXRalet86/OpG4kqw==
"@types/qs@*": "@types/qs@*":
version "6.9.5" version "6.9.5"
@@ -978,6 +985,13 @@ base@^0.11.1:
mixin-deep "^1.2.0" mixin-deep "^1.2.0"
pascalcase "^0.1.1" pascalcase "^0.1.1"
basic-auth@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a"
integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==
dependencies:
safe-buffer "5.1.2"
bcrypt-pbkdf@^1.0.0: bcrypt-pbkdf@^1.0.0:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
@@ -1136,9 +1150,9 @@ caseless@~0.12.0:
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
chai@^4.2.0: chai@^4.2.0:
version "4.2.0" version "4.3.0"
resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.0.tgz#5523a5faf7f819c8a92480d70a8cccbadacfc25f"
integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== integrity sha512-/BFd2J30EcOwmdOgXvVsmM48l0Br0nmZPlO0uOW4XKh6kpsUumRXBgPV+IlaqFaqr9cYbeoZAM1Npx0i4A+aiA==
dependencies: dependencies:
assertion-error "^1.1.0" assertion-error "^1.1.0"
check-error "^1.0.2" check-error "^1.0.2"
@@ -1554,6 +1568,11 @@ depd@~1.1.2:
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
depd@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
destroy@~1.0.4: destroy@~1.0.4:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
@@ -1866,9 +1885,9 @@ fast-safe-stringify@^2.0.4, fast-safe-stringify@^2.0.7:
integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==
fast-xml-parser@^3.17.4: fast-xml-parser@^3.17.4:
version "3.17.6" version "3.18.0"
resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.17.6.tgz#4f5df8cf927c3e59a10362abcfb7335c34bc5c5f" resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.18.0.tgz#b77f4a494cd64e6f44aadfa68fbde30cd922b2df"
integrity sha512-40WHI/5d2MOzf1sD2bSaTXlPn1lueJLAX6j1xH5dSAr6tNeut8B9ktEL6sjAK9yVON4uNj9//axOdBJUuruCzw== integrity sha512-tRrwShhppv0K5GKEtuVs92W0VGDaVltZAwtHbpjNF+JOT7cjIFySBGTEOmdBslXYyWYaZwEX/g4Su8ZeKg0LKQ==
fb-watchman@^2.0.0: fb-watchman@^2.0.0:
version "2.0.1" version "2.0.1"
@@ -1941,9 +1960,9 @@ forever-agent@~0.6.1:
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
form-data@^3.0.0: form-data@^3.0.0:
version "3.0.0" version "3.0.1"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f"
integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg== integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==
dependencies: dependencies:
asynckit "^0.4.0" asynckit "^0.4.0"
combined-stream "^1.0.8" combined-stream "^1.0.8"
@@ -1986,9 +2005,9 @@ fs.realpath@^1.0.0:
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
fsevents@^2.1.2, fsevents@~2.3.1: fsevents@^2.1.2, fsevents@~2.3.1:
version "2.3.1" version "2.3.2"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.1.tgz#b209ab14c61012636c8863507edf7fb68cc54e9f" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw== integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
function-bind@^1.1.1: function-bind@^1.1.1:
version "1.1.1" version "1.1.1"
@@ -2100,9 +2119,9 @@ got@^9.6.0:
url-parse-lax "^3.0.0" url-parse-lax "^3.0.0"
graceful-fs@^4.1.2, graceful-fs@^4.2.4: graceful-fs@^4.1.2, graceful-fs@^4.2.4:
version "4.2.4" version "4.2.6"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
growly@^1.3.0: growly@^1.3.0:
version "1.3.0" version "1.3.0"
@@ -2372,7 +2391,7 @@ is-ci@^2.0.0:
dependencies: dependencies:
ci-info "^2.0.0" ci-info "^2.0.0"
is-core-module@^2.1.0: is-core-module@^2.2.0:
version "2.2.0" version "2.2.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a"
integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==
@@ -3056,9 +3075,9 @@ json-stringify-safe@~5.0.1:
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
json5@2.x, json5@^2.1.2: json5@2.x, json5@^2.1.2:
version "2.1.3" version "2.2.0"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==
dependencies: dependencies:
minimist "^1.2.5" minimist "^1.2.5"
@@ -3318,6 +3337,17 @@ mkdirp@1.x:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
morgan@^1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7"
integrity sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==
dependencies:
basic-auth "~2.0.1"
debug "2.6.9"
depd "~2.0.0"
on-finished "~2.3.0"
on-headers "~1.0.2"
ms@2.0.0: ms@2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
@@ -3508,6 +3538,11 @@ on-finished@~2.3.0:
dependencies: dependencies:
ee-first "1.1.1" ee-first "1.1.1"
on-headers@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f"
integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==
once@^1.3.0, once@^1.3.1, once@^1.4.0: once@^1.3.0, once@^1.3.1, once@^1.4.0:
version "1.4.0" version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
@@ -3945,11 +3980,11 @@ resolve-url@^0.2.1:
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
resolve@^1.10.0, resolve@^1.18.1: resolve@^1.10.0, resolve@^1.18.1:
version "1.19.0" version "1.20.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
dependencies: dependencies:
is-core-module "^2.1.0" is-core-module "^2.2.0"
path-parse "^1.0.6" path-parse "^1.0.6"
responselike@^1.0.2: responselike@^1.0.2:
@@ -4214,9 +4249,9 @@ source-map-support@^0.5.17, source-map-support@^0.5.6:
source-map "^0.6.0" source-map "^0.6.0"
source-map-url@^0.4.0: source-map-url@^0.4.0:
version "0.4.0" version "0.4.1"
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56"
integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==
source-map@^0.5.0, source-map@^0.5.6: source-map@^0.5.0, source-map@^0.5.6:
version "0.5.7" version "0.5.7"
@@ -4573,9 +4608,9 @@ triple-beam@^1.2.0, triple-beam@^1.3.0:
integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==
ts-jest@^26.4.4: ts-jest@^26.4.4:
version "26.5.0" version "26.5.1"
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.5.0.tgz#3e3417d91bc40178a6716d7dacc5b0505835aa21" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.5.1.tgz#4d53ee4481552f57c1624f0bd3425c8b17996150"
integrity sha512-Ya4IQgvIFNa2Mgq52KaO8yBw2W8tWp61Ecl66VjF0f5JaV8u50nGoptHVILOPGoI7SDnShmEqnYQEmyHdQ+56g== integrity sha512-G7Rmo3OJMvlqE79amJX8VJKDiRcd7/r61wh9fnvvG8cAjhA9edklGw/dCxRSQmfZ/z8NDums5srSVgwZos1qfg==
dependencies: dependencies:
"@types/jest" "26.x" "@types/jest" "26.x"
bs-logger "0.x" bs-logger "0.x"
@@ -4668,9 +4703,9 @@ typedarray-to-buffer@^3.1.5:
is-typedarray "^1.0.0" is-typedarray "^1.0.0"
typescript@^4.1.3: typescript@^4.1.3:
version "4.1.3" version "4.1.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.5.tgz#123a3b214aaff3be32926f0d8f1f6e704eb89a72"
integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg== integrity sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA==
undefsafe@^2.0.3: undefsafe@^2.0.3:
version "2.0.3" version "2.0.3"
@@ -4944,9 +4979,9 @@ write-file-atomic@^3.0.0:
typedarray-to-buffer "^3.1.5" typedarray-to-buffer "^3.1.5"
ws@^7.2.3: ws@^7.2.3:
version "7.4.2" version "7.4.3"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.2.tgz#782100048e54eb36fe9843363ab1c68672b261dd" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.3.tgz#1f9643de34a543b8edb124bdcbc457ae55a6e5cd"
integrity sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA== integrity sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==
xdg-basedir@^4.0.0: xdg-basedir@^4.0.0:
version "4.0.0" version "4.0.0"
@@ -4971,11 +5006,21 @@ xmlchars@^2.2.0:
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
xmldom-ts@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/xmldom-ts/-/xmldom-ts-0.3.1.tgz#a70df029e44e9af3c03ba22d88f174a953830091"
integrity sha512-dmEBAK3Msm+BPVZOiwhXCyM0/q3BeiI4eoAPj2Us1nDhsPPhePtZ5RkgEdngNQQFp3j6QFKMLHlBIRUxdpomcQ==
xmldom@0.1.27: xmldom@0.1.27:
version "0.1.27" version "0.1.27"
resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9"
integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk= integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk=
xpath-ts@^1.3.13:
version "1.3.13"
resolved "https://registry.yarnpkg.com/xpath-ts/-/xpath-ts-1.3.13.tgz#abca4f15dd7010161acf5b9cd01566f7b8d9541f"
integrity sha512-eNVXzDWbCV9KEB6fGNQ3qHFGC9PWBH7y2h13vZ+CMPNqOTZ+fgYTG4Sb0p5bVHiAwZrzgE6/tx987003P3dYpA==
xpath@0.0.27: xpath@0.0.27:
version "0.0.27" version "0.0.27"
resolved "https://registry.yarnpkg.com/xpath/-/xpath-0.0.27.tgz#dd3421fbdcc5646ac32c48531b4d7e9d0c2cfa92" resolved "https://registry.yarnpkg.com/xpath/-/xpath-0.0.27.tgz#dd3421fbdcc5646ac32c48531b4d7e9d0c2cfa92"
@@ -4992,9 +5037,9 @@ yallist@^4.0.0:
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yargs-parser@20.x: yargs-parser@20.x:
version "20.2.4" version "20.2.5"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.5.tgz#5d37729146d3f894f39fc94b6796f5b239513186"
integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== integrity sha512-jYRGS3zWy20NtDtK2kBgo/TlAoy5YUuhD9/LZ7z7W4j1Fdw2cqD0xEEclf8fxc8xjD6X5Qr+qQQwCEsP8iRiYg==
yargs-parser@^18.1.2: yargs-parser@^18.1.2:
version "18.1.3" version "18.1.3"