use salt + md5 hash mode instead of plain text password
This commit is contained in:
+1
-2
@@ -49,7 +49,6 @@ export default Vue.extend({
|
||||
async created() {
|
||||
this.server = await this.$auth.server;
|
||||
this.username = await this.$auth.username;
|
||||
this.password = await this.$auth.password;
|
||||
const success = await this.$auth.autoLogin();
|
||||
if (success) {
|
||||
this.$store.commit("setLoginSuccess", { username: this.username});
|
||||
@@ -61,7 +60,7 @@ export default Vue.extend({
|
||||
methods: {
|
||||
login() {
|
||||
this.busy = true;
|
||||
this.$auth.login(this.server, this.username, this.password, this.rememberLogin)
|
||||
this.$auth.loginWithPassword(this.server, this.username, this.password, this.rememberLogin)
|
||||
.then(() => {
|
||||
this.$store.commit("setLoginSuccess", { username: this.username });
|
||||
this.$router.push(this.returnTo);
|
||||
|
||||
+18
-7
@@ -1,35 +1,45 @@
|
||||
import axios from 'axios';
|
||||
import { randomString, md5 } from '@/shared/utils';
|
||||
|
||||
|
||||
export class AuthService {
|
||||
public server: string = "";
|
||||
public username: string = "";
|
||||
public password: string = "";
|
||||
public salt: string = "";
|
||||
public hash: string = "";
|
||||
private authenticated: boolean = false;
|
||||
|
||||
constructor() {
|
||||
this.server = localStorage.getItem("server") || "/api";
|
||||
this.username = localStorage.getItem("username") || "guest1";
|
||||
this.password = localStorage.getItem("password") || "";
|
||||
this.salt = localStorage.getItem("salt") || "";
|
||||
this.hash = localStorage.getItem("hash") || "";
|
||||
}
|
||||
|
||||
private saveSession() {
|
||||
localStorage.setItem("server", this.server);
|
||||
localStorage.setItem("username", this.username);
|
||||
localStorage.setItem("password", this.password);
|
||||
localStorage.setItem("salt", this.salt);
|
||||
localStorage.setItem("hash", this.hash);
|
||||
}
|
||||
|
||||
async autoLogin(): Promise<boolean> {
|
||||
if (!this.server || !this.username) {
|
||||
return false;
|
||||
}
|
||||
return this.login(this.server, this.username, this.password, false)
|
||||
return this.loginWithHash(this.server, this.username, this.salt, this.hash, false)
|
||||
.then(() => true)
|
||||
.catch(() => false);
|
||||
}
|
||||
|
||||
async login(server: string, username: string, password: string, remember: boolean) {
|
||||
return axios.get(`${server}/rest/ping.view?u=${username}&p=${password}&v=1.15.0&c=app&f=json`)
|
||||
async loginWithPassword(server: string, username: string, password: string, remember: boolean) {
|
||||
const salt = randomString();
|
||||
const hash = md5(password + salt);
|
||||
return this.loginWithHash(server, username, salt, hash, remember);
|
||||
}
|
||||
|
||||
private async loginWithHash(server: string, username: string, salt: string, hash: string, remember: boolean) {
|
||||
return axios.get(`${server}/rest/ping.view?u=${username}&s=${salt}&t=${hash}&v=1.15.0&c=app&f=json`)
|
||||
.then((response) => {
|
||||
const subsonicResponse = response.data["subsonic-response"];
|
||||
if (!subsonicResponse || subsonicResponse.status !== "ok") {
|
||||
@@ -39,7 +49,8 @@ export class AuthService {
|
||||
this.authenticated = true;
|
||||
this.server = server;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.salt = salt;
|
||||
this.hash = hash;
|
||||
if (remember) {
|
||||
this.saveSession();
|
||||
}
|
||||
|
||||
+6
-5
@@ -16,7 +16,8 @@ export class API {
|
||||
config.params = config.params || {};
|
||||
config.baseURL = this.auth.server
|
||||
config.params.u = this.auth.username;
|
||||
config.params.p = this.auth.password;
|
||||
config.params.s = this.auth.salt;
|
||||
config.params.t = this.auth.hash;
|
||||
config.params.c = "app";
|
||||
config.params.f = "json";
|
||||
config.params.v = "1.15.0";
|
||||
@@ -255,12 +256,12 @@ export class API {
|
||||
if (!item.coverArt) {
|
||||
return undefined;
|
||||
}
|
||||
const { server, username, password } = this.auth;
|
||||
return `${server}/rest/getCoverArt?id=${item.coverArt}&v=1.15.0&u=${username}&p=${password}&c=test&size=300`
|
||||
const { server, username, salt, hash } = this.auth;
|
||||
return `${server}/rest/getCoverArt?id=${item.coverArt}&v=1.15.0&u=${username}&s=${salt}&t=${hash}&c=test&size=300`
|
||||
}
|
||||
|
||||
private getStreamUrl(id: any) {
|
||||
const { server, username, password } = this.auth;
|
||||
return `${server}/rest/stream?id=${id}&format=raw&v=1.15.0&u=${username}&p=${password}&c=test&size=300`
|
||||
const { server, username, salt, hash } = this.auth;
|
||||
return `${server}/rest/stream?id=${id}&format=raw&v=1.15.0&u=${username}&s=${salt}&t=${hash}&c=test&size=300`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import MD5 from 'md5-es';
|
||||
|
||||
export function randomString(): string {
|
||||
let arr = new Uint8Array(16);
|
||||
window.crypto.getRandomValues(arr);
|
||||
const validChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
arr = arr.map(x => validChars.charCodeAt(x % validChars.length));
|
||||
return String.fromCharCode.apply(null, Array.from(arr));
|
||||
}
|
||||
|
||||
export function md5(str: string): string {
|
||||
return MD5.hash(str);
|
||||
}
|
||||
Vendored
+2
@@ -2,3 +2,5 @@ declare module '*.vue' {
|
||||
import Vue from 'vue'
|
||||
export default Vue
|
||||
}
|
||||
|
||||
declare module "md5-es";
|
||||
Reference in New Issue
Block a user