mirror of
https://github.com/wkulhanek/bonob.git
synced 2025-12-21 17:33:29 +01:00
simple sonos smapi soap webservice registered
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
"eta": "^1.12.1",
|
||||
"express": "^4.17.1",
|
||||
"node-html-parser": "^2.1.0",
|
||||
"soap": "^0.36.0",
|
||||
"ts-md5": "^1.2.7",
|
||||
"typescript": "^4.1.3",
|
||||
"underscore":"^1.12.0",
|
||||
@@ -27,6 +28,7 @@
|
||||
"@types/mocha": "^8.2.0",
|
||||
"@types/supertest": "^2.0.10",
|
||||
"chai": "^4.2.0",
|
||||
"get-port": "^5.1.1",
|
||||
"jest": "^26.6.3",
|
||||
"nodemon": "^2.0.7",
|
||||
"supertest": "^6.1.3",
|
||||
@@ -38,6 +40,6 @@
|
||||
"build": "tsc",
|
||||
"dev": "nodemon ./src/app.ts",
|
||||
"test": "jest",
|
||||
"testw": "mocha --require ts-node/register --watch --watch-files tests/**/* tests/**/*.test.ts"
|
||||
"client-test": "ts-node tests/bonob_client.ts"
|
||||
}
|
||||
}
|
||||
|
||||
2066
src/Sonoswsdl-1.19.4-20190411.142401-3.wsdl
Normal file
2066
src/Sonoswsdl-1.19.4-20190411.142401-3.wsdl
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,16 @@
|
||||
import express, { Express } from "express";
|
||||
import * as Eta from "eta";
|
||||
import { listen } from "soap";
|
||||
import { readFileSync } from "fs";
|
||||
import path from "path";
|
||||
|
||||
import { Sonos, Service } from "./sonos";
|
||||
import logger from "./logger";
|
||||
|
||||
const WSDL_FILE = path.resolve(
|
||||
__dirname,
|
||||
"Sonoswsdl-1.19.4-20190411.142401-3.wsdl"
|
||||
);
|
||||
|
||||
function server(sonos: Sonos, bonobService: Service): Express {
|
||||
const app = express();
|
||||
@@ -12,26 +22,68 @@ function server(sonos: Sonos, bonobService: Service): Express {
|
||||
app.set("views", "./web/views");
|
||||
|
||||
app.get("/", (_, res) => {
|
||||
Promise.all([
|
||||
sonos.devices(),
|
||||
sonos.services()
|
||||
]).then(([devices, services]) => {
|
||||
const registeredBonobService = services.find(it => it.sid == bonobService.sid);
|
||||
Promise.all([sonos.devices(), sonos.services()]).then(
|
||||
([devices, services]) => {
|
||||
const registeredBonobService = services.find(
|
||||
(it) => it.sid == bonobService.sid
|
||||
);
|
||||
res.render("index", {
|
||||
devices,
|
||||
services,
|
||||
bonobService,
|
||||
registeredBonobService
|
||||
registeredBonobService,
|
||||
});
|
||||
})
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
app.post("/register", (_, res) => {
|
||||
sonos.register(bonobService).then(success => {
|
||||
if(success) res.send("Yay")
|
||||
else res.send("boo hoo")
|
||||
})
|
||||
sonos.register(bonobService).then((success) => {
|
||||
if (success) res.send("Yay");
|
||||
else res.send("boo hoo");
|
||||
});
|
||||
});
|
||||
|
||||
const sonosService = {
|
||||
Sonos: {
|
||||
SonosSoap: {
|
||||
getSessionId: ({
|
||||
username
|
||||
}: {
|
||||
username: string;
|
||||
password: string;
|
||||
}) => {
|
||||
return Promise.resolve({
|
||||
username,
|
||||
sessionId: '123'
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const x = listen(
|
||||
app,
|
||||
"/ws",
|
||||
sonosService,
|
||||
readFileSync(WSDL_FILE, "utf8")
|
||||
);
|
||||
|
||||
x.log = (type, data) => {
|
||||
switch (type) {
|
||||
case "info":
|
||||
logger.info({ data });
|
||||
break;
|
||||
case "warn":
|
||||
logger.warn({ data });
|
||||
break;
|
||||
case "error":
|
||||
logger.error({ data });
|
||||
break;
|
||||
default:
|
||||
logger.debug({ data });
|
||||
}
|
||||
};
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
33
tests/bonob_client.ts
Normal file
33
tests/bonob_client.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import getPort from "get-port";
|
||||
import { createClientAsync } from "soap";
|
||||
|
||||
import sonos, { bonobService } from "../src/sonos";
|
||||
import server from "../src/server";
|
||||
|
||||
import logger from "../src/logger";
|
||||
|
||||
const bonob = bonobService("bonob-test", 247, "http://localhost:1234");
|
||||
const app = server(sonos("disabled"), bonob);
|
||||
|
||||
getPort().then((port) => {
|
||||
logger.debug(`Starting on port ${port}`);
|
||||
app.listen(port);
|
||||
|
||||
createClientAsync(`http://localhost:${port}/ws?wsdl`, {
|
||||
endpoint: `http://localhost:${port}/ws`,
|
||||
}).then((client) => {
|
||||
client
|
||||
.getSessionIdAsync(
|
||||
{ username: "bob", password: "foo" }
|
||||
)
|
||||
.then(
|
||||
([{ username, sessionId }]: [
|
||||
{ username: string; sessionId: string }
|
||||
]) => {
|
||||
console.log(`${username} has sessionId=${sessionId}`);
|
||||
}
|
||||
);
|
||||
|
||||
console.log(`done`);
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"target": "es2019",
|
||||
"baseUrl": "./",
|
||||
"module": "commonjs",
|
||||
"experimentalDecorators": true,
|
||||
|
||||
54
tests/ws.test.ts
Normal file
54
tests/ws.test.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import request from "supertest";
|
||||
import makeServer from "../src/server";
|
||||
import { SONOS_DISABLED } from "../src/sonos";
|
||||
|
||||
import { aService } from "./builders";
|
||||
|
||||
import { createClientAsync } from "soap";
|
||||
|
||||
describe("ws", () => {
|
||||
describe("can call getSessionId", () => {
|
||||
it("should do something", async () => {
|
||||
const server = makeServer(SONOS_DISABLED, aService());
|
||||
|
||||
const { username, sessionId } = await createClientAsync(
|
||||
`http://localhost/ws?wsdl`,
|
||||
{
|
||||
endpoint: `http://localhost/ws`,
|
||||
httpClient: {
|
||||
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) =>
|
||||
client
|
||||
.getSessionIdAsync({ username: "bob", password: "foo" })
|
||||
.then(
|
||||
([{ username, sessionId }]: [
|
||||
{ username: string; sessionId: string }
|
||||
]) => ({
|
||||
username,
|
||||
sessionId,
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
expect(username).toEqual("bob");
|
||||
expect(sessionId).toEqual("123");
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/* Basic Options */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
"target": "ES6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
|
||||
"target": "ES2019", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
|
||||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
|
||||
"lib": ["es2019"], /* Specify library files to be included in the compilation. */
|
||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||
|
||||
73
yarn.lock
73
yarn.lock
@@ -2015,6 +2015,11 @@ get-package-type@^0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
|
||||
integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==
|
||||
|
||||
get-port@^5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193"
|
||||
integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==
|
||||
|
||||
get-stream@^4.0.0, get-stream@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
|
||||
@@ -2029,6 +2034,11 @@ get-stream@^5.0.0, get-stream@^5.1.0:
|
||||
dependencies:
|
||||
pump "^3.0.0"
|
||||
|
||||
get-stream@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.0.tgz#3e0012cb6827319da2706e601a1583e8629a6718"
|
||||
integrity sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==
|
||||
|
||||
get-value@^2.0.3, get-value@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
|
||||
@@ -2233,6 +2243,19 @@ http-signature@~1.2.0:
|
||||
jsprim "^1.2.2"
|
||||
sshpk "^1.7.0"
|
||||
|
||||
httpntlm@^1.5.2:
|
||||
version "1.7.6"
|
||||
resolved "https://registry.yarnpkg.com/httpntlm/-/httpntlm-1.7.6.tgz#6991e8352836007d67101b83db8ed0f915f906d0"
|
||||
integrity sha1-aZHoNSg2AH1nEBuD247Q+RX5BtA=
|
||||
dependencies:
|
||||
httpreq ">=0.4.22"
|
||||
underscore "~1.7.0"
|
||||
|
||||
httpreq@>=0.4.22:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/httpreq/-/httpreq-0.4.24.tgz#4335ffd82cd969668a39465c929ac61d6393627f"
|
||||
integrity sha1-QzX/2CzZaWaKOUZckprGHWOTYn8=
|
||||
|
||||
human-signals@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
|
||||
@@ -3868,7 +3891,7 @@ request-promise-native@^1.0.8:
|
||||
stealthy-require "^1.1.1"
|
||||
tough-cookie "^2.3.3"
|
||||
|
||||
request@^2.88.2:
|
||||
request@>=2.9.0, request@^2.88.2:
|
||||
version "2.88.2"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
||||
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
|
||||
@@ -3990,6 +4013,11 @@ sane@^4.0.3:
|
||||
minimist "^1.1.1"
|
||||
walker "~1.0.5"
|
||||
|
||||
sax@>=0.6:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
|
||||
|
||||
saxes@^5.0.0:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d"
|
||||
@@ -4151,6 +4179,21 @@ snapdragon@^0.8.1:
|
||||
source-map-resolve "^0.5.0"
|
||||
use "^3.1.0"
|
||||
|
||||
soap@^0.36.0:
|
||||
version "0.36.0"
|
||||
resolved "https://registry.yarnpkg.com/soap/-/soap-0.36.0.tgz#80d1a55e89e048f175ae5538c288428d8c649445"
|
||||
integrity sha512-MEFr2H7+a02fAA2FWyJE1B0xvDE8jiH5Ke6P1WKChHR9TGcJMK7kRAlPK/YR+NNO1pUs6W1FaIz4w8I9kuvybw==
|
||||
dependencies:
|
||||
debug "^4.1.1"
|
||||
get-stream "^6.0.0"
|
||||
httpntlm "^1.5.2"
|
||||
lodash "^4.17.19"
|
||||
request ">=2.9.0"
|
||||
sax ">=0.6"
|
||||
strip-bom "^3.0.0"
|
||||
uuid "^8.3.0"
|
||||
xml-crypto "^2.0.0"
|
||||
|
||||
source-map-resolve@^0.5.0:
|
||||
version "0.5.3"
|
||||
resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a"
|
||||
@@ -4332,6 +4375,11 @@ strip-ansi@^6.0.0:
|
||||
dependencies:
|
||||
ansi-regex "^5.0.0"
|
||||
|
||||
strip-bom@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
||||
integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
|
||||
|
||||
strip-bom@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878"
|
||||
@@ -4636,6 +4684,11 @@ underscore@^1.12.0:
|
||||
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.12.0.tgz#4814940551fc80587cef7840d1ebb0f16453be97"
|
||||
integrity sha512-21rQzss/XPMjolTiIezSu3JAjgagXKROtNrYFEOWK109qY1Uv2tVjPTZ1ci2HgvQDA16gHYSthQIJfB+XId/rQ==
|
||||
|
||||
underscore@~1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209"
|
||||
integrity sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=
|
||||
|
||||
union-value@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847"
|
||||
@@ -4900,6 +4953,14 @@ xdg-basedir@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
|
||||
integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==
|
||||
|
||||
xml-crypto@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/xml-crypto/-/xml-crypto-2.0.0.tgz#54cd268ad9d31930afcf7092cbb664258ca9e826"
|
||||
integrity sha512-/a04qr7RpONRZHOxROZ6iIHItdsQQjN3sj8lJkYDDss8tAkEaAs0VrFjb3tlhmS5snQru5lTs9/5ISSMdPDHlg==
|
||||
dependencies:
|
||||
xmldom "0.1.27"
|
||||
xpath "0.0.27"
|
||||
|
||||
xml-name-validator@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
|
||||
@@ -4910,6 +4971,16 @@ xmlchars@^2.2.0:
|
||||
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
|
||||
integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
|
||||
|
||||
xmldom@0.1.27:
|
||||
version "0.1.27"
|
||||
resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9"
|
||||
integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk=
|
||||
|
||||
xpath@0.0.27:
|
||||
version "0.0.27"
|
||||
resolved "https://registry.yarnpkg.com/xpath/-/xpath-0.0.27.tgz#dd3421fbdcc5646ac32c48531b4d7e9d0c2cfa92"
|
||||
integrity sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==
|
||||
|
||||
y18n@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4"
|
||||
|
||||
Reference in New Issue
Block a user