diff --git a/Makefile b/Makefile index dd7b3740..00ffb55d 100644 --- a/Makefile +++ b/Makefile @@ -137,4 +137,4 @@ build-windows-386: build: build-linux-arm-7 build-linux-amd64 build-linux-386 build-linux-arm64 build-linux-riscv64 build-windows-amd64 build-windows-386 -.PHONY: test-race test-coverage test check-go check-js verify-swagger check download-tools update-swagger package-zip build-docker build-js build +.PHONY: test-coverage test check-go check-js verify-swagger check download-tools update-swagger package-zip build-docker build-js build diff --git a/config/config.go b/config/config.go index a8fbc2fe..c94d98f5 100644 --- a/config/config.go +++ b/config/config.go @@ -4,8 +4,8 @@ import ( "path/filepath" "strings" - "github.com/gotify/configor" "github.com/gotify/server/v2/mode" + "github.com/jinzhu/configor" ) // Configuration is stuff that can be configured externally per env variables or config file (config.yml). @@ -66,7 +66,7 @@ func configFiles() []string { // Get returns the configuration extracted from env variables or config file. func Get() *Configuration { conf := new(Configuration) - err := configor.New(&configor.Config{EnvironmentPrefix: "GOTIFY"}).Load(conf, configFiles()...) + err := configor.New(&configor.Config{ENVPrefix: "GOTIFY"}).Load(conf, configFiles()...) if err != nil { panic(err) } diff --git a/go.mod b/go.mod index a6df9216..68288e7e 100644 --- a/go.mod +++ b/go.mod @@ -7,10 +7,10 @@ require ( github.com/gin-gonic/gin v1.10.0 github.com/go-playground/validator/v10 v10.22.1 github.com/gorilla/websocket v1.5.3 - github.com/gotify/configor v1.0.2 github.com/gotify/location v0.0.0-20170722210143-03bc4ad20437 github.com/gotify/plugin-api v1.0.0 github.com/h2non/filetype v1.1.3 + github.com/jinzhu/configor v1.2.2 github.com/jinzhu/gorm v1.9.16 github.com/robfig/cron v1.2.0 github.com/stretchr/testify v1.9.0 @@ -19,7 +19,7 @@ require ( ) require ( - github.com/BurntSushi/toml v0.3.1 // indirect + github.com/BurntSushi/toml v1.2.0 // indirect github.com/bytedance/sonic v1.11.6 // indirect github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/cloudwego/base64x v0.1.4 // indirect @@ -30,7 +30,6 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-sql-driver/mysql v1.5.0 // indirect - github.com/go-yaml/yaml v2.1.0+incompatible // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -43,7 +42,6 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect diff --git a/go.sum b/go.sum index 90959645..8f034759 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,5 @@ -github.com/BurntSushi/toml v0.3.0/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0= +github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= @@ -42,8 +41,6 @@ github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27 github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o= -github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= @@ -53,14 +50,14 @@ github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gotify/configor v1.0.2 h1:8uZKz6TpSup2dJKib8wz95KppQNtRMCmIl+eFY5uw+A= -github.com/gotify/configor v1.0.2/go.mod h1:bxVAr7YmnLR8cGik/M9ROkytPzr521/IwM5zLOfkHwk= github.com/gotify/location v0.0.0-20170722210143-03bc4ad20437 h1:4qMhogAexRcnvdoY9O1RoCuuuNEhDF25jtbGIWPtcms= github.com/gotify/location v0.0.0-20170722210143-03bc4ad20437/go.mod h1:5JgfyQg+71Ck3uXX/4FBHc4YxdKZ9shU8gs2AUj7Nj0= github.com/gotify/plugin-api v1.0.0 h1:kab40p2TEPLzjmcafOc7JOz75aTsYQyS2PXtElH8xmI= github.com/gotify/plugin-api v1.0.0/go.mod h1:xZfEyqVK/Zvu3RwA/CtpuiwFmzFDxifrrqMaH9BHnyU= github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg= github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= +github.com/jinzhu/configor v1.2.2 h1:sLgh6KMzpCmaQB4e+9Fu/29VErtBUqsS2t8C9BNIVsA= +github.com/jinzhu/configor v1.2.2/go.mod h1:iFFSfOBKP3kC2Dku0ZGB3t3aulfQgTGJknodhFavsU8= github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -96,9 +93,6 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= @@ -155,8 +149,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/ui/src/CurrentUser.ts b/ui/src/CurrentUser.ts index 6de4edb4..0d657f69 100644 --- a/ui/src/CurrentUser.ts +++ b/ui/src/CurrentUser.ts @@ -15,7 +15,7 @@ export class CurrentUser { @observable public loggedIn = false; @observable - public authenticating = false; + public authenticating = true; @observable public user: IUser = {name: 'unknown', admin: false, id: -1}; @observable @@ -80,17 +80,11 @@ export class CurrentUser { .then((resp: AxiosResponse) => { this.snack(`A client named '${name}' was created for your session.`); this.setToken(resp.data.token); - this.tryAuthenticate() - .then(() => { - this.authenticating = false; - this.loggedIn = true; - }) - .catch(() => { - this.authenticating = false; - console.log( - 'create client succeeded, but authenticated with given token failed' - ); - }); + this.tryAuthenticate().catch(() => { + console.log( + 'create client succeeded, but authenticated with given token failed' + ); + }); }) .catch(() => { this.authenticating = false; @@ -100,6 +94,7 @@ export class CurrentUser { public tryAuthenticate = async (): Promise> => { if (this.token() === '') { + this.authenticating = false; return Promise.reject(); } @@ -111,11 +106,13 @@ export class CurrentUser { .then((passThrough) => { this.user = passThrough.data; this.loggedIn = true; + this.authenticating = false; this.connectionErrorMessage = null; this.reconnectTime = 7500; return passThrough; }) .catch((error: AxiosError) => { + this.authenticating = false; if (!error || !error.response) { this.connectionError('No network connection or server unavailable.'); return Promise.reject(error); diff --git a/ui/src/common/BaseStore.ts b/ui/src/common/BaseStore.ts index 6b9a73db..4b2b4eee 100644 --- a/ui/src/common/BaseStore.ts +++ b/ui/src/common/BaseStore.ts @@ -30,6 +30,13 @@ export abstract class BaseStore implements IClearable { this.items = await this.requestItems().then((items) => items || []); }; + @action + public refreshIfMissing = async (id: number): Promise => { + if (this.getByIDOrUndefined(id) === undefined) { + await this.refresh(); + } + }; + public getByID = (id: number): T => { const item = this.getByIDOrUndefined(id); if (item === undefined) { diff --git a/ui/src/plugin/PluginDetailView.tsx b/ui/src/plugin/PluginDetailView.tsx index 0a27fad3..7c83877a 100644 --- a/ui/src/plugin/PluginDetailView.tsx +++ b/ui/src/plugin/PluginDetailView.tsx @@ -16,6 +16,7 @@ import * as config from '../config'; import Container from '../common/Container'; import {inject, Stores} from '../inject'; import {IPlugin} from '../types'; +import LoadingSpinner from '../common/LoadingSpinner'; type IProps = RouteComponentProps<{id: string}>; @@ -42,8 +43,9 @@ class PluginDetailView extends Component, IState> this.refreshFeatures(); } - private refreshFeatures() { - return Promise.all([this.refreshConfigurer(), this.refreshDisplayer()]); + private async refreshFeatures() { + await this.props.pluginStore.refreshIfMissing(this.pluginID); + return await Promise.all([this.refreshConfigurer(), this.refreshDisplayer()]); } private async refreshConfigurer() { @@ -67,14 +69,16 @@ class PluginDetailView extends Component, IState> } public render() { - const pluginInfo = this.pluginInfo(); - const {name, capabilities} = pluginInfo; + const pluginInfo = this.props.pluginStore.getByIDOrUndefined(this.pluginID); + if (pluginInfo === undefined) { + return ; + } return ( - + - {capabilities.indexOf('configurer') !== -1 ? ( + {pluginInfo.capabilities.indexOf('configurer') !== -1 ? ( , IState> /> ) : null}{' '} - {capabilities.indexOf('displayer') !== -1 ? ( + {pluginInfo.capabilities.indexOf('displayer') !== -1 ? ( { it('does login', async () => await auth.login(page)); - it('navigates to users', async () => { - await page.click('#navigate-users'); + it('navigates to users through window location', async () => { + await page.goto(gotify.url + '/#/users'); await waitForExists(page, selector.heading(), 'Users'); }); it('has changed url', async () => {