diff --git a/.vscode/launch.json b/.vscode/launch.json index 8c5fcbf..c1a30dd 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -52,6 +52,19 @@ "../zmap/frontend" ] }, + { + "name": "zmap frontend", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/main.go", + "args": [ + "--metafile", + "/home/ymnuk/projects/zmap/zmap.yml", + "--outdir-frontend", + "../zmap/frontend" + ] + }, { "name": "zmap docs", "type": "go", diff --git a/lib/templ/tmpl/backend/db/db.tmpl b/lib/templ/tmpl/backend/db/db.tmpl index 7e2b805..c1aaa63 100644 --- a/lib/templ/tmpl/backend/db/db.tmpl +++ b/lib/templ/tmpl/backend/db/db.tmpl @@ -137,7 +137,8 @@ func updateRoles() { ID: uuid.FromStringOrNil("{{ $field.ID }}"), }, Name: "{{ $field.Name }}", - Description: &[]string{"{{ $field.Display }}"}[0], + Display: &[]string{"{{ $field.Display }}"}[0], + Description: &[]string{"{{ $field.Description }}"}[0], }, {{ end }} } @@ -161,6 +162,7 @@ func updateRoles() { } // Обновление записи role.Name = item.Name + role.Display = item.Display role.Description = item.Description if res := tx.Save(&role); res.RowsAffected == 0 { if res := tx.Create(&item); res.RowsAffected == 0 { diff --git a/lib/templ/tmpl/backend/db/migrate.tmpl b/lib/templ/tmpl/backend/db/migrate.tmpl index df20cbc..2f4bfaf 100644 --- a/lib/templ/tmpl/backend/db/migrate.tmpl +++ b/lib/templ/tmpl/backend/db/migrate.tmpl @@ -12,7 +12,6 @@ func update{{ fieldNamePrepare $item.Name}}() { records := []model.{{ fieldNamePrepare $item.Name }} { {{ range $i, $field := $item.Values }} { - {{ range $name, $value := $field }} {{ if eq $name "id" }} Base: model.Base{ diff --git a/lib/templ/tmpl/backend/db/model/role.tmpl b/lib/templ/tmpl/backend/db/model/role.tmpl index c39db52..9a3a716 100644 --- a/lib/templ/tmpl/backend/db/model/role.tmpl +++ b/lib/templ/tmpl/backend/db/model/role.tmpl @@ -3,7 +3,8 @@ package model // Role Роли пользователей type Role struct { Base - Name string `gorm:"type:varchar(20);comment:Название роли" json:"name"` - Description *string `gorm:"type:text;comment:Отображаемое название/описание роли" json:"description"` + Name string `gorm:"type:varchar(30);comment:Название роли" json:"name"` + Display *string `gorm:"type:text;comment:Отображаемое название роли" json:"display"` + Description *string `gorm:"type:text;comment:Описание роли" json:"description"` UserRole []UserRole } diff --git a/lib/templ/tmpl/backend/route/api/user/role/index.tmpl b/lib/templ/tmpl/backend/route/api/user/role/index.tmpl index ca40119..894b975 100644 --- a/lib/templ/tmpl/backend/route/api/user/role/index.tmpl +++ b/lib/templ/tmpl/backend/route/api/user/role/index.tmpl @@ -38,7 +38,7 @@ func listRoles(c echo.Context) error { }() var roles []model.Role - if res := tx.Find(&roles); res.RowsAffected == 0 { + if res := tx.Order("display, name").Find(&roles); res.RowsAffected == 0 { return c.JSON(http.StatusNotFound, structs.Result{ Result: &[]bool{false}[0], Code: &[]int{http.StatusNotFound}[0], diff --git a/lib/templ/tmpl/docs/backend/roles-table.tmpl b/lib/templ/tmpl/docs/backend/roles-table.tmpl index f1e7f5c..692cd8d 100644 --- a/lib/templ/tmpl/docs/backend/roles-table.tmpl +++ b/lib/templ/tmpl/docs/backend/roles-table.tmpl @@ -1,4 +1,4 @@ -|Название|Описание| -|:-------|:-------| -{{ range $index, $role := .Roles }}|{{ $role.Name }}|{{ $role.Display }}| +|Название|Отображаемое название|Описание| +|:-------|:--------------------|:-------| +{{ range $index, $role := .Roles }}|{{ $role.Name }}|{{ $role.Display }}|{{ $role.Description }}| {{ end }} \ No newline at end of file diff --git a/lib/templ/tmpl/docs/index.tmpl b/lib/templ/tmpl/docs/index.tmpl index 20c85f9..85b57f6 100644 --- a/lib/templ/tmpl/docs/index.tmpl +++ b/lib/templ/tmpl/docs/index.tmpl @@ -4,3 +4,7 @@ {{ includeTemplPart "tmpl/docs/db/table-list.tmpl" .DB }} ![Полная структура БД](full-schemadb.svg "Полная структура БД") + +# Роли + +[Роли](roles.md) \ No newline at end of file diff --git a/lib/templ/tmpl/frontend/angular/src/app/page/user/user-form/user-form.component.html.tmpl b/lib/templ/tmpl/frontend/angular/src/app/page/user/user-form/user-form.component.html.tmpl index c7138ba..061638c 100644 --- a/lib/templ/tmpl/frontend/angular/src/app/page/user/user-form/user-form.component.html.tmpl +++ b/lib/templ/tmpl/frontend/angular/src/app/page/user/user-form/user-form.component.html.tmpl @@ -88,9 +88,10 @@
diff --git a/lib/templ/tmpl/frontend/angular/src/app/service/auth.service.ts.tmpl b/lib/templ/tmpl/frontend/angular/src/app/service/auth.service.ts.tmpl index d5e9619..50a06c1 100644 --- a/lib/templ/tmpl/frontend/angular/src/app/service/auth.service.ts.tmpl +++ b/lib/templ/tmpl/frontend/angular/src/app/service/auth.service.ts.tmpl @@ -22,20 +22,12 @@ export class AuthService { private {{ $value }}Service: {{ fieldNamePrepare $value }}Service, {{ end }} ) { - if (localStorage.getItem('auth-token') != null) { - this._tkn = localStorage.getItem('auth-token'); {{ range $index, $value := .Backend.RestGroups }} if (this.{{ $value }}Service.configuration.apiKeys == null) { this.{{ $value }}Service.configuration.apiKeys = {} } this.{{ $value }}Service.configuration.apiKeys['Authorization'] = `Bearer ${this._tkn}`; {{ end }} - - let jwt = jwt_decode(this.token as string); - if ((jwt as any).roles) { - this._roles = (jwt as any).roles; - } - } } login(login: ModelUser): Observable { @@ -44,32 +36,71 @@ export class AuthService { (result: StructsResult) => { localStorage.setItem('auth-token', result.data); this.token = result.data; - let jwt = jwt_decode(this.token as string); + /*let jwt = jwt_decode(this.token as string); if ((jwt as any).roles) { this._roles = (jwt as any).roles; - } + }*/ } ) ); } get token(): string | null { + if (this._tkn == null) { + if (localStorage.getItem('auth-token') != null) { + this._tkn = localStorage.getItem('auth-token'); + if (this._tkn != null) { + {{ range $index, $value := .Backend.RestGroups }} + if (this.{{ $value }}Service.configuration.apiKeys != null) { + this.{{ $value }}Service.configuration.apiKeys['Authorization'] = `Bearer ${this._tkn}`; + } + {{ end }} + } + } + } + if (this._tkn != null) { + let jwt = jwt_decode(this._tkn as string); + if ((jwt as any).roles) { + this._roles = (jwt as any).roles; + } + const d = new Date(0); + d.setUTCSeconds((jwt as any).exp); + if (d.getTime() < (new Date()).getTime()) { + this.token = null + this.router.navigate(['/login']) + } + } else { + this.router.navigate(['/login']) + } return this._tkn; } set token(value: string | null) { - this._tkn = value; - {{ range $index, $value := .Backend.RestGroups }} - if (this.{{ $value }}Service.configuration.apiKeys == null) { - this.{{ $value }}Service.configuration.apiKeys = {} + if (value == null) { + this._tkn = null; + localStorage.removeItem('auth-token'); + {{ range $index, $value := .Backend.RestGroups }} + if (this.{{ $value }}Service.configuration.apiKeys != null) { + delete this.{{ $value }}Service.configuration.apiKeys['Authorization']; + } + {{ end }} + } else { + this._tkn = value; + localStorage.setItem('auth-token', value); + {{ range $index, $value := .Backend.RestGroups }} + if (this.{{ $value }}Service.configuration.apiKeys != null) { + this.{{ $value }}Service.configuration.apiKeys['Authorization'] = `Bearer ${this._tkn}`; + } + {{ end }} + let jwt = jwt_decode(this.token as string); + if ((jwt as any).roles) { + this._roles = (jwt as any).roles; + } } - this.{{ $value }}Service.configuration.apiKeys['Authorization'] = `Bearer ${this._tkn}`; - {{ end }} - } isAuthenticated(): boolean { - return this._tkn != null; + return this.token != null; // return !!this.token; } diff --git a/structs/role.go b/structs/role.go index e855b7a..5937304 100644 --- a/structs/role.go +++ b/structs/role.go @@ -3,7 +3,8 @@ package structs import uuid "github.com/satori/go.uuid" type Role struct { - ID uuid.UUID `yaml:"id" json:"id"` - Name string `yaml:"name" json:"name"` - Display string `yaml:"display" json:"display"` + ID uuid.UUID `yaml:"id" json:"id"` + Name string `yaml:"name" json:"name"` + Display string `yaml:"display" json:"display"` + Description string `yaml:"description,omitempty" json:"description,omitempty"` }