Adding some css, fix message on log in failure

This commit is contained in:
simojenki
2021-03-02 11:54:27 +11:00
parent 06024e8e36
commit ce6c1638fd
10 changed files with 63 additions and 23 deletions

View File

@@ -22,10 +22,6 @@ export type AuthFailure = {
message: string; message: string;
}; };
export interface MusicService {
generateToken(credentials: Credentials): Promise<AuthSuccess | AuthFailure>;
login(authToken: string): Promise<MusicLibrary>;
}
export type Artist = { export type Artist = {
id: string; id: string;
@@ -64,6 +60,10 @@ export type ArtistQuery = Paging
export type AlbumQuery = Paging & { export type AlbumQuery = Paging & {
artistId?: string artistId?: string
} }
export interface MusicService {
generateToken(credentials: Credentials): Promise<AuthSuccess | AuthFailure>;
login(authToken: string): Promise<MusicLibrary>;
}
export interface MusicLibrary { export interface MusicLibrary {
artists(q: ArtistQuery): Promise<Result<Artist>>; artists(q: ArtistQuery): Promise<Result<Artist>>;

View File

@@ -1,5 +1,15 @@
import { Md5 } from "ts-md5/dist/md5"; import { Md5 } from "ts-md5/dist/md5";
import { Credentials, MusicService, Album, Artist, Result, slice2, asResult, AlbumQuery, ArtistQuery } from "./music_service"; import {
Credentials,
MusicService,
Album,
Artist,
Result,
slice2,
asResult,
AlbumQuery,
ArtistQuery,
} from "./music_service";
import X2JS from "x2js"; import X2JS from "x2js";
import axios from "axios"; import axios from "axios";
@@ -85,7 +95,7 @@ export class Navidrome implements MusicService {
).toString("base64"), ).toString("base64"),
userId: credentials.username, userId: credentials.username,
nickname: credentials.username, nickname: credentials.username,
})); })).catch(e => ({ message: `${e}` }));
parseToken = (token: string): Credentials => parseToken = (token: string): Credentials =>
JSON.parse( JSON.parse(

View File

@@ -83,11 +83,11 @@ function server(
if (isSuccess(authResult)) { if (isSuccess(authResult)) {
linkCodes.associate(linkCode, authResult); linkCodes.associate(linkCode, authResult);
res.render("success", { res.render("success", {
message: `Login successful`, message: `Login successful!`,
}); });
} else { } else {
res.status(403).render("failure", { res.status(403).render("failure", {
message: `Login failed, ${authResult.message}!`, message: `Login failed! ${authResult.message}!`,
}); });
} }
} }

View File

@@ -7,6 +7,7 @@ import axios from "axios";
jest.mock("axios"); jest.mock("axios");
import randomString from "../src/random_string"; import randomString from "../src/random_string";
import { AuthSuccess } from "../src/music_service";
jest.mock("../src/random_string"); jest.mock("../src/random_string");
describe("t", () => { describe("t", () => {
@@ -52,7 +53,7 @@ describe("navidrome", () => {
</subsonic-response>`, </subsonic-response>`,
}); });
const token = await navidrome.generateToken({ username, password }); const token = await navidrome.generateToken({ username, password }) as AuthSuccess;
expect(token.authToken).toBeDefined(); expect(token.authToken).toBeDefined();
expect(token.nickname).toEqual(username); expect(token.nickname).toEqual(username);
@@ -73,9 +74,8 @@ describe("navidrome", () => {
</subsonic-response>`, </subsonic-response>`,
}); });
return expect( const token = await navidrome.generateToken({ username, password });
navidrome.generateToken({ username, password }) expect(token).toEqual({ message: "Wrong username or password" })
).rejects.toMatch("Wrong username or password");
}); });
}); });
}); });
@@ -105,6 +105,7 @@ describe("navidrome", () => {
it("should return all the artists", async () => { it("should return all the artists", async () => {
const artists = await navidrome const artists = await navidrome
.generateToken({ username, password }) .generateToken({ username, password })
.then(it => it as AuthSuccess)
.then((it) => navidrome.login(it.authToken)) .then((it) => navidrome.login(it.authToken))
.then((it) => it.artists({ _index: 0, _count: 100 })); .then((it) => it.artists({ _index: 0, _count: 100 }));
@@ -126,6 +127,7 @@ describe("navidrome", () => {
it("should return only the correct page of artists", async () => { it("should return only the correct page of artists", async () => {
const artists = await navidrome const artists = await navidrome
.generateToken({ username, password }) .generateToken({ username, password })
.then(it => it as AuthSuccess)
.then((it) => navidrome.login(it.authToken)) .then((it) => navidrome.login(it.authToken))
.then((it) => it.artists({ _index: 1, _count: 2 })); .then((it) => it.artists({ _index: 1, _count: 2 }));

View File

@@ -138,7 +138,7 @@ describe("api", () => {
.send({ username, password, linkCode }) .send({ username, password, linkCode })
.expect(403); .expect(403);
expect(res.text).toContain(`Login failed, Invalid user:${username}`); expect(res.text).toContain(`Login failed! Invalid user:${username}`);
}); });
}); });

View File

@@ -1,5 +1,5 @@
<% layout('./layout', { title: "Failure" }) %> <% layout('./layout', { title: "Failure" }) %>
<div id="content"> <div id="content">
<h1><%= it.message %></h1> <h1 class="failure"><%= it.message %></h1>
</div> </div>

View File

@@ -1,8 +1,7 @@
<% layout('./layout') %> <% layout('./layout') %>
<div id="content"> <div id="content">
<h1>bonob service</h1> <h1><%= it.bonobService.name %> (<%= it.bonobService.sid %>)</h1>
<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>
<% if(it.registeredBonobService) { %> <% if(it.registeredBonobService) { %>

View File

@@ -2,6 +2,33 @@
<html lang="en"> <html lang="en">
<head> <head>
<title><%= it.title || "bonob" %></title> <title><%= it.title || "bonob" %></title>
<style>
body {
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;
}
div#content {
margin: auto;
width: 60%;
}
h1 {
font-size: 700%;
}
label {
font-size: 300%;
}
input {
font-size: 300%;
width: 80%;
}
input#submit {
margin-top: 100px
}
</style>
</head> </head>
<body> <body>
<%~ it.body %> <%~ it.body %>

View File

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

View File

@@ -1,5 +1,5 @@
<% layout('./layout', { title: "Yippee" }) %> <% layout('./layout', { title: "Yippee" }) %>
<div id="content"> <div id="content">
<h1><%= it.message %></h1> <h1 class="success"><%= it.message %></h1>
</div> </div>