Auth: Use "username" instead of "name" in the session API #98 #2796

Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
Michael Mayer 2022-10-24 09:21:39 +02:00
parent f54f98770a
commit a02ecf12de
10 changed files with 56 additions and 54 deletions

View file

@ -2350,9 +2350,9 @@
}
},
"node_modules/@types/node": {
"version": "18.11.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.3.tgz",
"integrity": "sha512-fNjDQzzOsZeKZu5NATgXUPsaFaTxeRgFXoosrHivTl8RGeV733OLawXsGfEk9a8/tySyZUyiZ6E8LcjPFZ2y1A=="
"version": "18.11.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.4.tgz",
"integrity": "sha512-BxcJpBu8D3kv/GZkx/gSMz6VnTJREBj/4lbzYOQueUOELkt8WrO6zAcSPmp9uRPEW/d+lUO8QK0W2xnS1hEU0A=="
},
"node_modules/@types/parse-json": {
"version": "4.0.0",
@ -3903,9 +3903,9 @@
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
},
"node_modules/core-js": {
"version": "3.25.5",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.25.5.tgz",
"integrity": "sha512-nbm6eZSjm+ZuBQxCUPQKQCoUEfFOXjUZ8dTTyikyKaWrTYmAVbykQfwsKE5dBK88u3QCkCrzsx/PPlKfhsvgpw==",
"version": "3.26.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.0.tgz",
"integrity": "sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw==",
"hasInstallScript": true,
"funding": {
"type": "opencollective",
@ -3913,9 +3913,9 @@
}
},
"node_modules/core-js-compat": {
"version": "3.25.5",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.5.tgz",
"integrity": "sha512-ovcyhs2DEBUIE0MGEKHP4olCUW/XYte3Vroyxuh38rD1wAO4dHohsovUC4eAOuzFxE6b+RXvBU3UZ9o0YhUTkA==",
"version": "3.26.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.0.tgz",
"integrity": "sha512-piOX9Go+Z4f9ZiBFLnZ5VrOpBl0h7IGCkiFUN11QTe6LjAvOT3ifL/5TdoizMh99hcGy5SoLyWbapIY/PIb/3A==",
"dependencies": {
"browserslist": "^4.21.4"
},
@ -12147,9 +12147,9 @@
}
},
"node_modules/uglify-js": {
"version": "3.17.3",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.3.tgz",
"integrity": "sha512-JmMFDME3iufZnBpyKL+uS78LRiC+mK55zWfM5f/pWBJfpOttXAqYfdDGRukYhJuyRinvPVAtUhvy7rlDybNtFg==",
"version": "3.17.4",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz",
"integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==",
"optional": true,
"bin": {
"uglifyjs": "bin/uglifyjs"
@ -14827,9 +14827,9 @@
}
},
"@types/node": {
"version": "18.11.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.3.tgz",
"integrity": "sha512-fNjDQzzOsZeKZu5NATgXUPsaFaTxeRgFXoosrHivTl8RGeV733OLawXsGfEk9a8/tySyZUyiZ6E8LcjPFZ2y1A=="
"version": "18.11.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.4.tgz",
"integrity": "sha512-BxcJpBu8D3kv/GZkx/gSMz6VnTJREBj/4lbzYOQueUOELkt8WrO6zAcSPmp9uRPEW/d+lUO8QK0W2xnS1hEU0A=="
},
"@types/parse-json": {
"version": "4.0.0",
@ -16036,14 +16036,14 @@
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
},
"core-js": {
"version": "3.25.5",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.25.5.tgz",
"integrity": "sha512-nbm6eZSjm+ZuBQxCUPQKQCoUEfFOXjUZ8dTTyikyKaWrTYmAVbykQfwsKE5dBK88u3QCkCrzsx/PPlKfhsvgpw=="
"version": "3.26.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.0.tgz",
"integrity": "sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw=="
},
"core-js-compat": {
"version": "3.25.5",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.5.tgz",
"integrity": "sha512-ovcyhs2DEBUIE0MGEKHP4olCUW/XYte3Vroyxuh38rD1wAO4dHohsovUC4eAOuzFxE6b+RXvBU3UZ9o0YhUTkA==",
"version": "3.26.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.0.tgz",
"integrity": "sha512-piOX9Go+Z4f9ZiBFLnZ5VrOpBl0h7IGCkiFUN11QTe6LjAvOT3ifL/5TdoizMh99hcGy5SoLyWbapIY/PIb/3A==",
"requires": {
"browserslist": "^4.21.4"
}
@ -21848,9 +21848,9 @@
"integrity": "sha512-f9BESNVhzlhEFf2CHMSj40NWOjYPl1YKYbrvIr/hFTDEmLq7SRbWvm7FcdcpCYT95zrOhC7gZSxjdnnTpBcwVw=="
},
"uglify-js": {
"version": "3.17.3",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.3.tgz",
"integrity": "sha512-JmMFDME3iufZnBpyKL+uS78LRiC+mK55zWfM5f/pWBJfpOttXAqYfdDGRukYhJuyRinvPVAtUhvy7rlDybNtFg==",
"version": "3.17.4",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz",
"integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==",
"optional": true
},
"uid-safe": {

View file

@ -294,10 +294,10 @@ export default class Session {
return LoginPage === window.location.href.substring(window.location.href.lastIndexOf("/") + 1);
}
login(name, password, token) {
login(username, password, token) {
this.deleteId();
return Api.post("session", { name, password, token }).then((resp) => {
return Api.post("session", { username, password, token }).then((resp) => {
const reload = this.config.getLanguage() !== resp.data?.config?.settings?.ui?.language;
this.setResp(resp);
this.sendClientInfo();

View file

@ -10,16 +10,16 @@
</div>
<v-spacer></v-spacer>
<v-text-field
v-model="name"
v-model="username"
required hide-details solo flat light autofocus
type="text"
:disabled="loading"
name="name"
name="username"
autocorrect="off"
autocapitalize="none"
:label="$gettext('Name')"
background-color="grey lighten-5"
class="input-name text-selectable"
class="input-username text-selectable"
:color="colors.accent"
:placeholder="$gettext('Name')"
prepend-icon="person"
@ -108,7 +108,7 @@ export default {
},
loading: false,
showPassword: false,
name: "",
username: "",
password: "",
sponsor: this.$config.isSponsor(),
config: this.$config.values,
@ -120,7 +120,7 @@ export default {
},
computed: {
loginDisabled() {
return this.loading || this.name.trim() === "" || this.password.trim() === "";
return this.loading || this.username.trim() === "" || this.password.trim() === "";
}
},
created() {
@ -147,15 +147,15 @@ export default {
setTimeout(() => { window.location = route.href; }, 100);
},
login() {
const name = this.name.trim();
const username = this.username.trim();
const password = this.password.trim();
if (name === "" || password === "") {
if (username === "" || password === "") {
return;
}
this.loading = true;
this.$session.login(name, password).then(
this.$session.login(username, password).then(
() => {
this.load();
}

View file

@ -18,12 +18,12 @@ test.meta("testID", "authentication-001").meta({ type: "short", mode: "auth" })(
await t.navigateTo("/library/browse");
await t
.expect(page.nameInput.visible)
.expect(page.usernameInput.visible)
.ok()
.expect(Selector(".input-search input").visible)
.notOk();
await t.typeText(page.nameInput, "admin", { replace: true });
await t.typeText(page.usernameInput, "admin", { replace: true });
await t.expect(page.loginAction.hasAttribute("disabled", "disabled")).ok();
@ -46,14 +46,14 @@ test.meta("testID", "authentication-001").meta({ type: "short", mode: "auth" })(
await page.logout();
await t
.expect(page.nameInput.visible)
.expect(page.usernameInput.visible)
.ok()
.expect(Selector(".input-search input").visible)
.notOk();
await t.navigateTo("/library/settings");
await t
.expect(page.nameInput.visible)
.expect(page.usernameInput.visible)
.ok()
.expect(Selector(".input-search input").visible)
.notOk();
@ -67,7 +67,7 @@ test.meta("testID", "authentication-002").meta({ type: "short", mode: "auth" })(
await t.navigateTo("/library/favorites");
await t
.expect(page.nameInput.visible)
.expect(page.usernameInput.visible)
.ok()
.expect(Selector(".input-search input").visible)
.notOk();
@ -76,7 +76,7 @@ test.meta("testID", "authentication-002").meta({ type: "short", mode: "auth" })(
await t.navigateTo("/library/archive");
await t
.expect(page.nameInput.visible)
.expect(page.usernameInput.visible)
.ok()
.expect(Selector(".input-search input").visible)
.notOk();
@ -130,7 +130,7 @@ test.meta("testID", "authentication-003").meta({ type: "short", mode: "auth" })(
await t.navigateTo("/library/archive");
await t
.expect(page.nameInput.visible)
.expect(page.usernameInput.visible)
.ok()
.expect(Selector(".input-search input").visible)
.notOk();

View file

@ -37,7 +37,7 @@ test.meta("testID", "components-001").meta({ mode: "auth" })(
await toolbar.triggerMobileMenuAction("logout");
await t
.expect(page.nameInput.visible)
.expect(page.usernameInput.visible)
.ok()
.expect(Selector(".input-search input").visible)
.notOk();

View file

@ -23,7 +23,7 @@ export default class Page {
this.cardTitle = Selector("button.action-title-edit", { timeout: 7000 });
this.cardDescription = Selector('div[title="Description"]', { timeout: 7000 });
this.cardLocation = Selector("button.action-location", { timeout: 7000 });
this.nameInput = Selector(".input-name input", { timeout: 7000 });
this.usernameInput = Selector(".input-username input", { timeout: 7000 });
this.passwordInput = Selector(".input-password input", { timeout: 7000 });
this.togglePasswordMode = Selector(".v-input__icon--append", { timeout: 7000 });
this.loginAction = Selector(".action-confirm", { timeout: 7000 });
@ -31,7 +31,7 @@ export default class Page {
async login(username, password) {
await t
.typeText(Selector(".input-name input"), username, { replace: true, timeout: 5000 })
.typeText(Selector(".input-username input"), username, { replace: true, timeout: 5000 })
.typeText(Selector(".input-password input"), password, { replace: true })
.click(Selector(".action-confirm"));
}

2
go.mod
View file

@ -38,7 +38,7 @@ require (
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58
github.com/sevlyar/go-daemon v0.1.6
github.com/sirupsen/logrus v1.9.0
github.com/stretchr/testify v1.8.0
github.com/stretchr/testify v1.8.1
github.com/studio-b12/gowebdav v0.0.0-20211106090535-29e74efa701f
github.com/tensorflow/tensorflow v1.15.2
github.com/tidwall/gjson v1.14.3

4
go.sum
View file

@ -910,6 +910,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@ -918,8 +919,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/studio-b12/gowebdav v0.0.0-20211106090535-29e74efa701f h1:SLJx0nHhb2ZLlYNMAbrYsjwmVwXx4yRT48lNIxOp7ts=
github.com/studio-b12/gowebdav v0.0.0-20211106090535-29e74efa701f/go.mod h1:gCcfDlA1Y7GqOaeEKw5l9dOGx1VLdc/HuQSlQAaZ30s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=

View file

@ -34,7 +34,7 @@ func TestCreateSession(t *testing.T) {
defer conf.SetAuthMode(config.AuthModePublic)
CreateSession(router)
r := PerformRequestWithBody(app, http.MethodPost, "/api/v1/session", `{"name": "admin", "password": "photoprism"}`)
r := PerformRequestWithBody(app, http.MethodPost, "/api/v1/session", `{"username": "admin", "password": "photoprism"}`)
log.Debugf("BODY: %s", r.Body.String())
val2 := gjson.Get(r.Body.String(), "user.Name")
assert.Equal(t, "admin", val2.String())
@ -46,7 +46,7 @@ func TestCreateSession(t *testing.T) {
defer conf.SetAuthMode(config.AuthModePublic)
CreateSession(router)
r := PerformRequestWithBody(app, http.MethodPost, "/api/v1/session", `{"name": 123, "password": "xxx"}`)
r := PerformRequestWithBody(app, http.MethodPost, "/api/v1/session", `{"username": 123, "password": "xxx"}`)
assert.Equal(t, http.StatusBadRequest, r.Code)
})
t.Run("PublicInvalidToken", func(t *testing.T) {
@ -55,7 +55,7 @@ func TestCreateSession(t *testing.T) {
defer conf.SetAuthMode(config.AuthModePublic)
CreateSession(router)
r := PerformRequestWithBody(app, http.MethodPost, "/api/v1/session", `{"name": "admin", "password": "photoprism", "token": "xxx"}`)
r := PerformRequestWithBody(app, http.MethodPost, "/api/v1/session", `{"username": "admin", "password": "photoprism", "token": "xxx"}`)
assert.Equal(t, http.StatusNotFound, r.Code)
})
t.Run("AdminInvalidToken", func(t *testing.T) {
@ -89,7 +89,7 @@ func TestCreateSession(t *testing.T) {
t.Run("PublicValidToken", func(t *testing.T) {
app, router, _ := NewApiTest()
CreateSession(router)
r := PerformRequestWithBody(app, http.MethodPost, "/api/v1/session", `{"name": "admin", "password": "photoprism", "token": "1jxf3jfn2k"}`)
r := PerformRequestWithBody(app, http.MethodPost, "/api/v1/session", `{"username": "admin", "password": "photoprism", "token": "1jxf3jfn2k"}`)
assert.Equal(t, http.StatusOK, r.Code)
})
t.Run("AdminInvalidPassword", func(t *testing.T) {
@ -115,7 +115,7 @@ func TestCreateSession(t *testing.T) {
CreateSession(router)
r := PerformRequestWithBody(app, http.MethodPost, "/api/v1/session", `{"name": "alice", "password": "Alice123!"}`)
r := PerformRequestWithBody(app, http.MethodPost, "/api/v1/session", `{"username": "alice", "password": "Alice123!"}`)
userEmail := gjson.Get(r.Body.String(), "user.Email")
userName := gjson.Get(r.Body.String(), "user.Name")
assert.Equal(t, "alice@example.com", userEmail.String())
@ -128,7 +128,7 @@ func TestCreateSession(t *testing.T) {
defer conf.SetAuthMode(config.AuthModePublic)
CreateSession(router)
r := PerformRequestWithBody(app, http.MethodPost, "/api/v1/session", `{"name": "bob", "password": "Bobbob123!"}`)
r := PerformRequestWithBody(app, http.MethodPost, "/api/v1/session", `{"username": "bob", "password": "Bobbob123!"}`)
userEmail := gjson.Get(r.Body.String(), "user.Email")
userName := gjson.Get(r.Body.String(), "user.Name")
assert.Equal(t, "bob@example.com", userEmail.String())
@ -141,7 +141,7 @@ func TestCreateSession(t *testing.T) {
defer conf.SetAuthMode(config.AuthModePublic)
CreateSession(router)
r := PerformRequestWithBody(app, http.MethodPost, "/api/v1/session", `{"name": "bob", "password": "helloworld"}`)
r := PerformRequestWithBody(app, http.MethodPost, "/api/v1/session", `{"username": "bob", "password": "helloworld"}`)
val := gjson.Get(r.Body.String(), "error")
assert.Equal(t, i18n.Msg(i18n.ErrInvalidCredentials), val.String())
assert.Equal(t, http.StatusUnauthorized, r.Code)

View file

@ -6,7 +6,7 @@ import (
// Login represents a login form.
type Login struct {
UserName string `json:"name,omitempty"`
UserName string `json:"username,omitempty"`
UserEmail string `json:"email,omitempty"`
Password string `json:"password,omitempty"`
AuthToken string `json:"token,omitempty"`