mirror of
https://github.com/simon987/task_tracker.git
synced 2025-04-19 18:16:45 +00:00
some work on sessions
This commit is contained in:
parent
6ad42366ea
commit
f577e76afa
116
api/auth.go
116
api/auth.go
@ -3,19 +3,39 @@ package api
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/kataras/go-sessions"
|
|
||||||
"github.com/simon987/task_tracker/storage"
|
"github.com/simon987/task_tracker/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const MaxUsernameLength = 16
|
||||||
|
|
||||||
type LoginRequest struct {
|
type LoginRequest struct {
|
||||||
Username []byte
|
Username string `json:"username"`
|
||||||
Password []byte
|
Password string `json:"password"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type LoginResponse struct {
|
type LoginResponse struct {
|
||||||
Ok bool
|
Ok bool `json:"ok"`
|
||||||
Message string
|
Message string `json:"message,omitempty"`
|
||||||
Manager *storage.Manager
|
Manager *storage.Manager `json:"manager"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RegisterRequest struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountDetails struct {
|
||||||
|
LoggedIn bool `json:"logged_in"`
|
||||||
|
Manager *storage.Manager `json:"manager,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RegisterRequest) isValid() bool {
|
||||||
|
return len(r.Username) <= MaxUsernameLength
|
||||||
|
}
|
||||||
|
|
||||||
|
type RegisterResponse struct {
|
||||||
|
Ok bool `json:"ok"`
|
||||||
|
Message string `json:"message,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *WebAPI) Login(r *Request) {
|
func (api *WebAPI) Login(r *Request) {
|
||||||
@ -31,10 +51,10 @@ func (api *WebAPI) Login(r *Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
manager, err := api.Database.ValidateCredentials(req.Username, req.Password)
|
manager, err := api.Database.ValidateCredentials([]byte(req.Username), []byte(req.Password))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).WithFields(logrus.Fields{
|
logrus.WithError(err).WithFields(logrus.Fields{
|
||||||
"username": string(manager.Username),
|
"username": req.Username,
|
||||||
}).Warning("Login attempt")
|
}).Warning("Login attempt")
|
||||||
|
|
||||||
r.Json(LoginResponse{
|
r.Json(LoginResponse{
|
||||||
@ -44,10 +64,88 @@ func (api *WebAPI) Login(r *Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sess := sessions.StartFasthttp(r.Ctx)
|
sess := api.Session.StartFasthttp(r.Ctx)
|
||||||
sess.Set("manager", manager)
|
sess.Set("manager", manager)
|
||||||
|
|
||||||
|
logrus.Debug("SET")
|
||||||
|
logrus.Debug(sess.ID())
|
||||||
|
logrus.Debug(manager)
|
||||||
|
|
||||||
|
r.OkJson(LoginResponse{
|
||||||
|
Manager: manager,
|
||||||
|
Ok: true,
|
||||||
|
})
|
||||||
|
|
||||||
logrus.WithFields(logrus.Fields{
|
logrus.WithFields(logrus.Fields{
|
||||||
"username": string(manager.Username),
|
"username": string(manager.Username),
|
||||||
}).Info("Logged in")
|
}).Info("Logged in")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *WebAPI) Register(r *Request) {
|
||||||
|
|
||||||
|
req := &RegisterRequest{}
|
||||||
|
err := json.Unmarshal(r.Ctx.Request.Body(), req)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
r.Json(LoginResponse{
|
||||||
|
Ok: false,
|
||||||
|
Message: "Could not parse request",
|
||||||
|
}, 400)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !req.isValid() {
|
||||||
|
r.Json(LoginResponse{
|
||||||
|
Ok: false,
|
||||||
|
Message: "Invalid register request",
|
||||||
|
}, 400)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
manager := &storage.Manager{
|
||||||
|
Username: string(req.Username),
|
||||||
|
}
|
||||||
|
|
||||||
|
err = api.Database.SaveManager(manager, []byte(req.Password))
|
||||||
|
if err != nil {
|
||||||
|
logrus.WithError(err).WithFields(logrus.Fields{
|
||||||
|
"username": string(manager.Username),
|
||||||
|
}).Warning("Register attempt")
|
||||||
|
|
||||||
|
r.Json(LoginResponse{
|
||||||
|
Ok: false,
|
||||||
|
Message: err.Error(),
|
||||||
|
}, 400)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sess := api.Session.StartFasthttp(r.Ctx)
|
||||||
|
sess.Set("manager", manager)
|
||||||
|
|
||||||
|
r.OkJson(RegisterResponse{
|
||||||
|
Ok: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
logrus.WithFields(logrus.Fields{
|
||||||
|
"username": string(manager.Username),
|
||||||
|
}).Info("Registered")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *WebAPI) AccountDetails(r *Request) {
|
||||||
|
|
||||||
|
sess := api.Session.StartFasthttp(r.Ctx)
|
||||||
|
manager := sess.Get("manager")
|
||||||
|
logrus.Debug("GET")
|
||||||
|
logrus.Debug(sess.ID())
|
||||||
|
|
||||||
|
if manager == nil {
|
||||||
|
r.OkJson(AccountDetails{
|
||||||
|
LoggedIn: false,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
r.OkJson(AccountDetails{
|
||||||
|
LoggedIn: true,
|
||||||
|
Manager: manager.(*storage.Manager),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -39,6 +39,10 @@ func (e *LogRequest) Time() time.Time {
|
|||||||
func LogRequestMiddleware(h RequestHandler) fasthttp.RequestHandler {
|
func LogRequestMiddleware(h RequestHandler) fasthttp.RequestHandler {
|
||||||
return fasthttp.RequestHandler(func(ctx *fasthttp.RequestCtx) {
|
return fasthttp.RequestHandler(func(ctx *fasthttp.RequestCtx) {
|
||||||
|
|
||||||
|
ctx.Response.Header.Add("Access-Control-Allow-Headers", "Content-Type")
|
||||||
|
ctx.Response.Header.Add("Access-Control-Allow-Methods", "GET, POST, OPTION")
|
||||||
|
ctx.Response.Header.Add("Access-Control-Allow-Origin", "*")
|
||||||
|
|
||||||
logrus.WithFields(logrus.Fields{
|
logrus.WithFields(logrus.Fields{
|
||||||
"path": string(ctx.Path()),
|
"path": string(ctx.Path()),
|
||||||
"header": ctx.Request.Header.String(),
|
"header": ctx.Request.Header.String(),
|
||||||
|
17
api/main.go
17
api/main.go
@ -14,7 +14,8 @@ type WebAPI struct {
|
|||||||
server *fasthttp.Server
|
server *fasthttp.Server
|
||||||
router *fasthttprouter.Router
|
router *fasthttprouter.Router
|
||||||
Database *storage.Database
|
Database *storage.Database
|
||||||
SessionConfig *sessions.Config
|
SessionConfig sessions.Config
|
||||||
|
Session *sessions.Sessions
|
||||||
}
|
}
|
||||||
|
|
||||||
type Info struct {
|
type Info struct {
|
||||||
@ -38,11 +39,15 @@ func New() *WebAPI {
|
|||||||
|
|
||||||
api.router = &fasthttprouter.Router{}
|
api.router = &fasthttprouter.Router{}
|
||||||
|
|
||||||
api.SessionConfig = &sessions.Config{
|
api.SessionConfig = sessions.Config{
|
||||||
Cookie: config.Cfg.SessionCookieName,
|
Cookie: config.Cfg.SessionCookieName,
|
||||||
Expires: config.Cfg.SessionCookieExpiration,
|
Expires: config.Cfg.SessionCookieExpiration,
|
||||||
|
CookieSecureTLS: false,
|
||||||
|
DisableSubdomainPersistence: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
api.Session = sessions.New(api.SessionConfig)
|
||||||
|
|
||||||
api.server = &fasthttp.Server{
|
api.server = &fasthttp.Server{
|
||||||
Handler: api.router.Handler,
|
Handler: api.router.Handler,
|
||||||
Name: info.Name,
|
Name: info.Name,
|
||||||
@ -76,6 +81,10 @@ func New() *WebAPI {
|
|||||||
|
|
||||||
api.router.POST("/logs", LogRequestMiddleware(api.GetLog))
|
api.router.POST("/logs", LogRequestMiddleware(api.GetLog))
|
||||||
|
|
||||||
|
api.router.POST("/register", LogRequestMiddleware(api.Register))
|
||||||
|
api.router.POST("/login", LogRequestMiddleware(api.Login))
|
||||||
|
api.router.GET("/account", LogRequestMiddleware(api.AccountDetails))
|
||||||
|
|
||||||
api.router.NotFound = func(ctx *fasthttp.RequestCtx) {
|
api.router.NotFound = func(ctx *fasthttp.RequestCtx) {
|
||||||
|
|
||||||
if ctx.Request.Header.IsOptions() {
|
if ctx.Request.Header.IsOptions() {
|
||||||
|
@ -15,3 +15,7 @@ git:
|
|||||||
log:
|
log:
|
||||||
# panic, fatal, error, warn, info, debug, trace
|
# panic, fatal, error, warn, info, debug, trace
|
||||||
level: "trace"
|
level: "trace"
|
||||||
|
|
||||||
|
session:
|
||||||
|
cookie_name: "tt"
|
||||||
|
expiration: "25m"
|
||||||
|
@ -76,8 +76,8 @@ CREATE TABLE log_entry
|
|||||||
CREATE TABLE manager
|
CREATE TABLE manager
|
||||||
(
|
(
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
username TEXT,
|
username TEXT UNIQUE,
|
||||||
password TEXT,
|
password BYTEA,
|
||||||
website_admin BOOLEAN
|
website_admin BOOLEAN
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -62,13 +62,14 @@ func (database *Database) SaveManager(manager *Manager, password []byte) error {
|
|||||||
|
|
||||||
hash := crypto.SHA512.New()
|
hash := crypto.SHA512.New()
|
||||||
hash.Write(password)
|
hash.Write(password)
|
||||||
|
hash.Write([]byte(manager.Username))
|
||||||
hashedPassword := hash.Sum(nil)
|
hashedPassword := hash.Sum(nil)
|
||||||
|
|
||||||
row := db.QueryRow(`INSERT INTO manager (username, password, website_admin)
|
row := db.QueryRow(`INSERT INTO manager (username, password, website_admin)
|
||||||
VALUES ($1,$2,$3) RETURNING ID`,
|
VALUES ($1,$2,$3) RETURNING ID`,
|
||||||
manager.Username, hashedPassword, manager.WebsiteAdmin)
|
manager.Username, hashedPassword, manager.WebsiteAdmin)
|
||||||
|
|
||||||
err := row.Scan(manager.Id)
|
err := row.Scan(&manager.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).WithFields(logrus.Fields{
|
logrus.WithError(err).WithFields(logrus.Fields{
|
||||||
"username": manager,
|
"username": manager,
|
||||||
@ -100,22 +101,23 @@ func (database *Database) UpdateManager(manager *Manager) {
|
|||||||
}).Warning("Database.UpdateManager UPDATE")
|
}).Warning("Database.UpdateManager UPDATE")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (database *Database) UpdateManagerPassword(id int64, newPassword []byte) {
|
func (database *Database) UpdateManagerPassword(manager *Manager, newPassword []byte) {
|
||||||
|
|
||||||
hash := crypto.SHA512.New()
|
hash := crypto.SHA512.New()
|
||||||
|
hash.Write([]byte(manager.Username))
|
||||||
hash.Write(newPassword)
|
hash.Write(newPassword)
|
||||||
hashedPassword := hash.Sum(nil)
|
hashedPassword := hash.Sum(nil)
|
||||||
|
|
||||||
db := database.getDB()
|
db := database.getDB()
|
||||||
|
|
||||||
res, err := db.Exec(`UPDATE manager SET password=$1 WHERE id=$2`,
|
res, err := db.Exec(`UPDATE manager SET password=$1 WHERE id=$2`,
|
||||||
hashedPassword, id)
|
hashedPassword, manager.Id)
|
||||||
handleErr(err)
|
handleErr(err)
|
||||||
|
|
||||||
rowsAffected, _ := res.RowsAffected()
|
rowsAffected, _ := res.RowsAffected()
|
||||||
|
|
||||||
logrus.WithError(err).WithFields(logrus.Fields{
|
logrus.WithError(err).WithFields(logrus.Fields{
|
||||||
"rowsAffected": rowsAffected,
|
"rowsAffected": rowsAffected,
|
||||||
"id": id,
|
"id": manager.Id,
|
||||||
}).Warning("Database.UpdateManagerPassword UPDATE")
|
}).Warning("Database.UpdateManagerPassword UPDATE")
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ func (database *Database) UpdateProject(project *Project) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (database Database) GetAllProjects() *[]Project {
|
func (database Database) GetAllProjects() *[]Project {
|
||||||
var projects []Project
|
projects := make([]Project, 0)
|
||||||
|
|
||||||
db := database.getDB()
|
db := database.getDB()
|
||||||
rows, err := db.Query(`SELECT
|
rows, err := db.Query(`SELECT
|
||||||
|
@ -15,5 +15,5 @@ log:
|
|||||||
level: "trace"
|
level: "trace"
|
||||||
|
|
||||||
session:
|
session:
|
||||||
cookie_name: "tt"
|
cookie_name: "tt_test"
|
||||||
expiration: "25m"
|
expiration: "25m"
|
77
web/angular/package-lock.json
generated
77
web/angular/package-lock.json
generated
@ -1262,7 +1262,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
|
||||||
"integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
|
"integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"delegates": "^1.0.0",
|
"delegates": "^1.0.0",
|
||||||
"readable-stream": "^2.0.6"
|
"readable-stream": "^2.0.6"
|
||||||
@ -2516,8 +2515,7 @@
|
|||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"constants-browserify": {
|
"constants-browserify": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
@ -2919,8 +2917,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||||
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"depd": {
|
"depd": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
@ -3995,8 +3992,7 @@
|
|||||||
"ansi-regex": {
|
"ansi-regex": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"aproba": {
|
"aproba": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
@ -4017,14 +4013,12 @@
|
|||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
@ -4039,20 +4033,17 @@
|
|||||||
"code-point-at": {
|
"code-point-at": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"concat-map": {
|
"concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"console-control-strings": {
|
"console-control-strings": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"core-util-is": {
|
"core-util-is": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
@ -4169,8 +4160,7 @@
|
|||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"ini": {
|
"ini": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.5",
|
||||||
@ -4182,7 +4172,6 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"number-is-nan": "^1.0.0"
|
"number-is-nan": "^1.0.0"
|
||||||
}
|
}
|
||||||
@ -4197,7 +4186,6 @@
|
|||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
}
|
}
|
||||||
@ -4205,14 +4193,12 @@
|
|||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "0.0.8",
|
"version": "0.0.8",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
"version": "2.3.5",
|
"version": "2.3.5",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "^5.1.2",
|
"safe-buffer": "^5.1.2",
|
||||||
"yallist": "^3.0.0"
|
"yallist": "^3.0.0"
|
||||||
@ -4231,7 +4217,6 @@
|
|||||||
"version": "0.5.1",
|
"version": "0.5.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"minimist": "0.0.8"
|
"minimist": "0.0.8"
|
||||||
}
|
}
|
||||||
@ -4312,8 +4297,7 @@
|
|||||||
"number-is-nan": {
|
"number-is-nan": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"object-assign": {
|
"object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
@ -4325,7 +4309,6 @@
|
|||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
@ -4411,8 +4394,7 @@
|
|||||||
"safe-buffer": {
|
"safe-buffer": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"safer-buffer": {
|
"safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
@ -4448,7 +4430,6 @@
|
|||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"code-point-at": "^1.0.0",
|
"code-point-at": "^1.0.0",
|
||||||
"is-fullwidth-code-point": "^1.0.0",
|
"is-fullwidth-code-point": "^1.0.0",
|
||||||
@ -4468,7 +4449,6 @@
|
|||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"ansi-regex": "^2.0.0"
|
"ansi-regex": "^2.0.0"
|
||||||
}
|
}
|
||||||
@ -4512,14 +4492,12 @@
|
|||||||
"wrappy": {
|
"wrappy": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"yallist": {
|
"yallist": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -4528,7 +4506,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
|
||||||
"integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
|
"integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"graceful-fs": "^4.1.2",
|
"graceful-fs": "^4.1.2",
|
||||||
"inherits": "~2.0.0",
|
"inherits": "~2.0.0",
|
||||||
@ -4541,7 +4518,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
|
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
|
||||||
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
|
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"aproba": "^1.0.3",
|
"aproba": "^1.0.3",
|
||||||
"console-control-strings": "^1.0.0",
|
"console-control-strings": "^1.0.0",
|
||||||
@ -4579,8 +4555,7 @@
|
|||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
|
||||||
"integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
|
"integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"get-stream": {
|
"get-stream": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
@ -4805,8 +4780,7 @@
|
|||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||||
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
|
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"has-value": {
|
"has-value": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
@ -5562,8 +5536,7 @@
|
|||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
|
||||||
"integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
|
"integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"is-windows": {
|
"is-windows": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
@ -6246,7 +6219,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
|
||||||
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
|
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"graceful-fs": "^4.1.2",
|
"graceful-fs": "^4.1.2",
|
||||||
"parse-json": "^2.2.0",
|
"parse-json": "^2.2.0",
|
||||||
@ -6259,8 +6231,7 @@
|
|||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||||
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -6534,8 +6505,7 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
|
||||||
"integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
|
"integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"map-visit": {
|
"map-visit": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
@ -7167,7 +7137,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
|
||||||
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
|
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"are-we-there-yet": "~1.1.2",
|
"are-we-there-yet": "~1.1.2",
|
||||||
"console-control-strings": "~1.1.0",
|
"console-control-strings": "~1.1.0",
|
||||||
@ -8259,7 +8228,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
|
||||||
"integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
|
"integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"load-json-file": "^1.0.0",
|
"load-json-file": "^1.0.0",
|
||||||
"normalize-package-data": "^2.3.2",
|
"normalize-package-data": "^2.3.2",
|
||||||
@ -8271,7 +8239,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
|
||||||
"integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
|
"integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"graceful-fs": "^4.1.2",
|
"graceful-fs": "^4.1.2",
|
||||||
"pify": "^2.0.0",
|
"pify": "^2.0.0",
|
||||||
@ -8282,8 +8249,7 @@
|
|||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||||
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -8292,7 +8258,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
|
||||||
"integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
|
"integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"find-up": "^1.0.0",
|
"find-up": "^1.0.0",
|
||||||
"read-pkg": "^1.0.0"
|
"read-pkg": "^1.0.0"
|
||||||
@ -8303,7 +8268,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
|
||||||
"integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
|
"integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"path-exists": "^2.0.0",
|
"path-exists": "^2.0.0",
|
||||||
"pinkie-promise": "^2.0.0"
|
"pinkie-promise": "^2.0.0"
|
||||||
@ -8314,7 +8278,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
|
||||||
"integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
|
"integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"pinkie-promise": "^2.0.0"
|
"pinkie-promise": "^2.0.0"
|
||||||
}
|
}
|
||||||
@ -9605,7 +9568,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
|
||||||
"integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
|
"integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"is-utf8": "^0.2.0"
|
"is-utf8": "^0.2.0"
|
||||||
}
|
}
|
||||||
@ -10936,7 +10898,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
|
||||||
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
|
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"string-width": "^1.0.2 || 2"
|
"string-width": "^1.0.2 || 2"
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
<pre>
|
||||||
|
{{authService.account | json}}
|
||||||
|
</pre>
|
@ -0,0 +1,17 @@
|
|||||||
|
import {Component, OnInit} from '@angular/core';
|
||||||
|
import {AuthService} from "../auth.service";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-account-details',
|
||||||
|
templateUrl: './account-details.component.html',
|
||||||
|
styleUrls: ['./account-details.component.css']
|
||||||
|
})
|
||||||
|
export class AccountDetailsComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor(private authService: AuthService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,11 +1,16 @@
|
|||||||
import {Injectable} from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
import {HttpClient} from "@angular/common/http";
|
import {HttpClient} from "@angular/common/http";
|
||||||
import {Project} from "./models/project";
|
import {Project} from "./models/project";
|
||||||
|
import {Credentials} from "./models/credentials";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ApiService {
|
export class ApiService {
|
||||||
|
|
||||||
private url: string = "http://localhost:42901";
|
private url: string = "http://localhost/api";
|
||||||
|
private options: {
|
||||||
|
withCredentials: true,
|
||||||
|
responseType: "json"
|
||||||
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private http: HttpClient,
|
private http: HttpClient,
|
||||||
@ -13,22 +18,36 @@ export class ApiService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getLogs() {
|
getLogs() {
|
||||||
return this.http.post(this.url + "/logs", "{\"level\":6, \"since\":1}");
|
return this.http.post(this.url + "/logs", "{\"level\":6, \"since\":1}", this.options);
|
||||||
}
|
}
|
||||||
|
|
||||||
getProjects() {
|
getProjects() {
|
||||||
return this.http.get(this.url + "/project/list")
|
return this.http.get(this.url + "/project/list", this.options)
|
||||||
}
|
}
|
||||||
|
|
||||||
getProject(id: number) {
|
getProject(id: number) {
|
||||||
return this.http.get(this.url + "/project/get/" + id)
|
return this.http.get(this.url + "/project/get/" + id, this.options)
|
||||||
}
|
}
|
||||||
|
|
||||||
createProject(project: Project) {
|
createProject(project: Project) {
|
||||||
return this.http.post(this.url + "/project/create", project)
|
return this.http.post(this.url + "/project/create", project, this.options)
|
||||||
}
|
}
|
||||||
|
|
||||||
updateProject(project: Project) {
|
updateProject(project: Project) {
|
||||||
return this.http.post(this.url + "/project/update/" + project.id, project)
|
return this.http.post(this.url + "/project/update/" + project.id, project, this.options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
register(credentials: Credentials) {
|
||||||
|
return this.http.post(this.url + "/register", credentials, this.options)
|
||||||
|
}
|
||||||
|
|
||||||
|
login(credentials: Credentials) {
|
||||||
|
return this.http.post(this.url + "/login", credentials, this.options)
|
||||||
|
}
|
||||||
|
|
||||||
|
getAccountDetails() {
|
||||||
|
return this.http.get(this.url + "/account", this.options)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,12 @@ import {Title} from "@angular/platform-browser";
|
|||||||
import {filter} from "rxjs/operators";
|
import {filter} from "rxjs/operators";
|
||||||
import {TranslateService} from "@ngx-translate/core";
|
import {TranslateService} from "@ngx-translate/core";
|
||||||
import {LoginComponent} from "./login/login.component";
|
import {LoginComponent} from "./login/login.component";
|
||||||
import {CreateAccountComponent} from "./create-account/create-account.component";
|
import {AccountDetailsComponent} from "./account-details/account-details.component";
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{path: "log", component: LogsComponent},
|
{path: "log", component: LogsComponent},
|
||||||
{path: "login", component: LoginComponent},
|
{path: "login", component: LoginComponent},
|
||||||
{path: "new_account", component: CreateAccountComponent},
|
{path: "account", component: AccountDetailsComponent},
|
||||||
{path: "projects", component: ProjectListComponent},
|
{path: "projects", component: ProjectListComponent},
|
||||||
{path: "project/:id", component: ProjectDashboardComponent},
|
{path: "project/:id", component: ProjectDashboardComponent},
|
||||||
{path: "project/:id/update", component: UpdateProjectComponent},
|
{path: "project/:id/update", component: UpdateProjectComponent},
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
<button mat-button [class.mat-accent]="router.url == '/projects'" class="nav-link" [routerLink]="'projects'">{{"nav.project_list" | translate}}</button>
|
<button mat-button [class.mat-accent]="router.url == '/projects'" class="nav-link" [routerLink]="'projects'">{{"nav.project_list" | translate}}</button>
|
||||||
<button mat-button [class.mat-accent]="router.url == '/new_project'" class="nav-link" [routerLink]="'new_project'">{{"nav.new_project" | translate}}</button>
|
<button mat-button [class.mat-accent]="router.url == '/new_project'" class="nav-link" [routerLink]="'new_project'">{{"nav.new_project" | translate}}</button>
|
||||||
<span class="nav-spacer"></span>
|
<span class="nav-spacer"></span>
|
||||||
|
<button mat-button [class.mat-accent]="router.url == '/login'" class="nav-link"
|
||||||
|
[routerLink]="'login'">{{"nav.login" | translate}}</button>
|
||||||
<mat-form-field [floatLabel]="'never'">
|
<mat-form-field [floatLabel]="'never'">
|
||||||
<mat-select [placeholder]="'nav.langSelect' | translate" (selectionChange)="langChange($event)">
|
<mat-select [placeholder]="'nav.langSelect' | translate" (selectionChange)="langChange($event)">
|
||||||
<mat-option *ngFor="let lang of langList" [value]="lang.lang">
|
<mat-option *ngFor="let lang of langList" [value]="lang.lang">
|
||||||
|
@ -19,12 +19,14 @@ import {
|
|||||||
MatMenuModule,
|
MatMenuModule,
|
||||||
MatPaginatorIntl,
|
MatPaginatorIntl,
|
||||||
MatPaginatorModule,
|
MatPaginatorModule,
|
||||||
|
MatProgressBarModule,
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
MatSliderModule,
|
MatSliderModule,
|
||||||
MatSlideToggleModule,
|
MatSlideToggleModule,
|
||||||
MatSnackBarModule,
|
MatSnackBarModule,
|
||||||
MatSortModule,
|
MatSortModule,
|
||||||
MatTableModule,
|
MatTableModule,
|
||||||
|
MatTabsModule,
|
||||||
MatToolbarModule,
|
MatToolbarModule,
|
||||||
MatTreeModule
|
MatTreeModule
|
||||||
} from "@angular/material";
|
} from "@angular/material";
|
||||||
@ -41,7 +43,7 @@ import {TranslateLoader, TranslateModule, TranslateService} from "@ngx-translate
|
|||||||
import {TranslateHttpLoader} from "@ngx-translate/http-loader";
|
import {TranslateHttpLoader} from "@ngx-translate/http-loader";
|
||||||
import {TranslatedPaginator} from "./TranslatedPaginatorConfiguration";
|
import {TranslatedPaginator} from "./TranslatedPaginatorConfiguration";
|
||||||
import {LoginComponent} from './login/login.component';
|
import {LoginComponent} from './login/login.component';
|
||||||
import {CreateAccountComponent} from './create-account/create-account.component';
|
import {AccountDetailsComponent} from './account-details/account-details.component';
|
||||||
|
|
||||||
|
|
||||||
export function createTranslateLoader(http: HttpClient) {
|
export function createTranslateLoader(http: HttpClient) {
|
||||||
@ -59,7 +61,7 @@ export function createTranslateLoader(http: HttpClient) {
|
|||||||
UpdateProjectComponent,
|
UpdateProjectComponent,
|
||||||
SnackBarComponent,
|
SnackBarComponent,
|
||||||
LoginComponent,
|
LoginComponent,
|
||||||
CreateAccountComponent,
|
AccountDetailsComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
@ -94,7 +96,9 @@ export function createTranslateLoader(http: HttpClient) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
MatSelectModule
|
MatSelectModule,
|
||||||
|
MatProgressBarModule,
|
||||||
|
MatTabsModule
|
||||||
|
|
||||||
],
|
],
|
||||||
exports: [],
|
exports: [],
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
mat-form-field {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
<div class="small-container">
|
|
||||||
<mat-card class="mat-elevation-z8">
|
|
||||||
<mat-card-title>{{"create_account.title" | translate}}</mat-card-title>
|
|
||||||
<mat-card-content style="padding: 2em 0 1em">
|
|
||||||
<form>
|
|
||||||
<mat-form-field appearance="outline" [hideRequiredMarker]="true">
|
|
||||||
<mat-label>{{"login.username" | translate}}</mat-label>
|
|
||||||
<mat-hint align="end">{{credentials.username?.length || 0}}/16</mat-hint>
|
|
||||||
<input maxlength="16" type="text" matInput [(ngModel)]="credentials.username" name="username"
|
|
||||||
required>
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<mat-form-field appearance="outline" [hideRequiredMarker]="true">
|
|
||||||
<mat-label>{{ "login.password" | translate}}</mat-label>
|
|
||||||
<input type="password" matInput [(ngModel)]="credentials.password" name="password" required>
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<mat-form-field appearance="outline">
|
|
||||||
<mat-label>{{ "login.repeat_password" | translate}}</mat-label>
|
|
||||||
<input type="password" matInput [(ngModel)]="credentials.repeatPassword" name="password2"
|
|
||||||
>
|
|
||||||
</mat-form-field>
|
|
||||||
</form>
|
|
||||||
</mat-card-content>
|
|
||||||
<mat-card-actions>
|
|
||||||
<button mat-raised-button color="primary" [disabled]="!canCreate()"
|
|
||||||
(click)="onClick()">{{"create_account.create" | translate}}</button>
|
|
||||||
</mat-card-actions>
|
|
||||||
</mat-card>
|
|
||||||
</div>
|
|
@ -1,28 +0,0 @@
|
|||||||
import {Component, OnInit} from '@angular/core';
|
|
||||||
import {Credentials} from "../models/credentials";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-create-account',
|
|
||||||
templateUrl: './create-account.component.html',
|
|
||||||
styleUrls: ['./create-account.component.css']
|
|
||||||
})
|
|
||||||
export class CreateAccountComponent implements OnInit {
|
|
||||||
|
|
||||||
credentials: Credentials = <Credentials>{};
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
}
|
|
||||||
|
|
||||||
canCreate(): boolean {
|
|
||||||
return this.credentials.username && this.credentials.username != "" &&
|
|
||||||
this.credentials.password == this.credentials.repeatPassword
|
|
||||||
}
|
|
||||||
|
|
||||||
onClick() {
|
|
||||||
alert("e")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -12,7 +12,7 @@ import {Router} from "@angular/router";
|
|||||||
})
|
})
|
||||||
export class CreateProjectComponent implements OnInit {
|
export class CreateProjectComponent implements OnInit {
|
||||||
|
|
||||||
project = new Project();
|
project = <Project>{};
|
||||||
|
|
||||||
constructor(private apiService: ApiService,
|
constructor(private apiService: ApiService,
|
||||||
private messengerService: MessengerService,
|
private messengerService: MessengerService,
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
.mat-form-field {
|
.mat-form-field {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pad {
|
||||||
|
padding-top: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<div class="small-container">
|
<div class="small-container">
|
||||||
<mat-card class="mat-elevation-z8">
|
<mat-card class="mat-elevation-z8">
|
||||||
<mat-card-title>{{"login.title" | translate}}</mat-card-title>
|
|
||||||
<mat-card-content style="padding: 2em 0 1em">
|
<mat-tab-group>
|
||||||
<form>
|
<mat-tab [label]="'login.title' | translate" class="pad">
|
||||||
<mat-form-field appearance="outline">
|
<mat-form-field appearance="outline">
|
||||||
<mat-label>{{"login.username" | translate}}</mat-label>
|
<mat-label>{{"login.username" | translate}}</mat-label>
|
||||||
<input type="text" matInput [(ngModel)]="credentials.username">
|
<input type="text" matInput [(ngModel)]="credentials.username">
|
||||||
@ -12,11 +12,32 @@
|
|||||||
<mat-label>{{ "login.password" | translate}}</mat-label>
|
<mat-label>{{ "login.password" | translate}}</mat-label>
|
||||||
<input type="password" matInput [(ngModel)]="credentials.password">
|
<input type="password" matInput [(ngModel)]="credentials.password">
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</form>
|
|
||||||
</mat-card-content>
|
<button mat-raised-button color="primary"
|
||||||
<mat-card-actions>
|
(click)="login()">{{"login.login" | translate}}</button>
|
||||||
<button mat-raised-button color="primary"
|
</mat-tab>
|
||||||
(click)="onClick()">{{"login.login" | translate}}</button>
|
<mat-tab [label]="'create_account.title' | translate" class="pad">
|
||||||
</mat-card-actions>
|
<mat-form-field appearance="outline" [hideRequiredMarker]="true">
|
||||||
|
<mat-label>{{"login.username" | translate}}</mat-label>
|
||||||
|
<mat-hint align="end">{{credentials.username?.length || 0}}/16</mat-hint>
|
||||||
|
<input maxlength="16" type="text" matInput [(ngModel)]="credentials.username" name="username"
|
||||||
|
required>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="outline" [hideRequiredMarker]="true">
|
||||||
|
<mat-label>{{ "login.password" | translate}}</mat-label>
|
||||||
|
<input type="password" matInput [(ngModel)]="credentials.password" name="password" required>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>{{ "login.repeat_password" | translate}}</mat-label>
|
||||||
|
<input type="password" matInput [(ngModel)]="credentials.repeatPassword" name="password2"
|
||||||
|
>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<button mat-raised-button color="primary" [disabled]="!canCreate()"
|
||||||
|
(click)="register()">{{"create_account.create" | translate}}</button>
|
||||||
|
</mat-tab>
|
||||||
|
</mat-tab-group>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
import {Component, OnInit} from '@angular/core';
|
import {Component, OnInit} from '@angular/core';
|
||||||
import {Credentials} from "../models/credentials";
|
import {Credentials} from "../models/credentials";
|
||||||
|
import {ApiService} from "../api.service";
|
||||||
|
import {MessengerService} from "../messenger.service";
|
||||||
|
import {Router} from "@angular/router";
|
||||||
|
import {AuthService} from "../auth.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-login',
|
selector: 'app-login',
|
||||||
@ -10,13 +14,34 @@ export class LoginComponent implements OnInit {
|
|||||||
|
|
||||||
credentials: Credentials = <Credentials>{};
|
credentials: Credentials = <Credentials>{};
|
||||||
|
|
||||||
constructor() {
|
constructor(private apiService: ApiService,
|
||||||
|
private messengerService: MessengerService,
|
||||||
|
private router: Router,
|
||||||
|
private authService: AuthService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
onClick() {
|
login() {
|
||||||
|
this.authService.login(this.credentials)
|
||||||
|
}
|
||||||
|
|
||||||
|
register() {
|
||||||
|
this.apiService.register(this.credentials)
|
||||||
|
.subscribe(
|
||||||
|
() => {
|
||||||
|
this.router.navigateByUrl("/account")
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
console.log(error);
|
||||||
|
this.messengerService.show(error.error.message);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
canCreate(): boolean {
|
||||||
|
return this.credentials.username && this.credentials.username != "" &&
|
||||||
|
this.credentials.password == this.credentials.repeatPassword
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import {Component, OnInit, ViewChild} from '@angular/core';
|
import {Component, OnInit, ViewChild} from '@angular/core';
|
||||||
import {ApiService} from "../api.service";
|
import {ApiService} from "../api.service";
|
||||||
|
import {LogEntry} from "../models/logentry";
|
||||||
|
|
||||||
import _ from "lodash"
|
import _ from "lodash"
|
||||||
import * as moment from "moment";
|
import * as moment from "moment";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
interface LogEntry {
|
export interface LogEntry {
|
||||||
level: string,
|
level: string,
|
||||||
message: string,
|
message: string,
|
||||||
data: any,
|
data: any,
|
3
web/angular/src/app/models/manager.ts
Normal file
3
web/angular/src/app/models/manager.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
interface Manager {
|
||||||
|
username: string
|
||||||
|
}
|
@ -1,11 +1,10 @@
|
|||||||
export class Project {
|
export interface Project {
|
||||||
|
id: number;
|
||||||
public id: number;
|
priority: number;
|
||||||
public priority: number;
|
motd: string;
|
||||||
public motd: string;
|
name: string;
|
||||||
public name: string;
|
clone_url: string;
|
||||||
public clone_url: string;
|
git_repo: string;
|
||||||
public git_repo: string;
|
version: string;
|
||||||
public version: string;
|
public: boolean;
|
||||||
public public: boolean;
|
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,11 @@
|
|||||||
<mat-icon>build</mat-icon>{{"project.update" | translate}}</button>
|
<mat-icon>build</mat-icon>{{"project.update" | translate}}</button>
|
||||||
</div>
|
</div>
|
||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
|
<span *ngIf="projects && projects.length == 0">
|
||||||
|
{{"projects.empty" | translate}}
|
||||||
|
</span>
|
||||||
|
<mat-progress-bar mode="indeterminate"
|
||||||
|
*ngIf="projects == null"></mat-progress-bar>
|
||||||
</mat-accordion>
|
</mat-accordion>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
"langSelect": "Language",
|
"langSelect": "Language",
|
||||||
"logs": "Logs",
|
"logs": "Logs",
|
||||||
"project_list": "Projects",
|
"project_list": "Projects",
|
||||||
"new_project": "New Project"
|
"new_project": "New Project",
|
||||||
|
"login": "Login"
|
||||||
},
|
},
|
||||||
"logs": {
|
"logs": {
|
||||||
"filter": "Filter",
|
"filter": "Filter",
|
||||||
@ -21,7 +22,8 @@
|
|||||||
},
|
},
|
||||||
"projects": {
|
"projects": {
|
||||||
"projects": "Projects",
|
"projects": "Projects",
|
||||||
"dashboard": "Dashboard"
|
"dashboard": "Dashboard",
|
||||||
|
"empty": "No projects"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"": "Index",
|
"": "Index",
|
||||||
@ -30,7 +32,8 @@
|
|||||||
"log": "Logs",
|
"log": "Logs",
|
||||||
"new_project": "New project",
|
"new_project": "New project",
|
||||||
"login": "Login",
|
"login": "Login",
|
||||||
"new_account": "Create account"
|
"new_account": "Create account",
|
||||||
|
"account": "Account details"
|
||||||
},
|
},
|
||||||
"project": {
|
"project": {
|
||||||
"name": "Project name",
|
"name": "Project name",
|
||||||
@ -51,14 +54,15 @@
|
|||||||
"metadata": "Project metadata"
|
"metadata": "Project metadata"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Manager login",
|
"title": "Login",
|
||||||
"login": "Login",
|
"login": "Login",
|
||||||
"username": "Username",
|
"username": "Username",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"repeat_password": "Repeat password"
|
"repeat_password": "Repeat password",
|
||||||
|
"create_account": ""
|
||||||
},
|
},
|
||||||
"create_account": {
|
"create_account": {
|
||||||
"title": "Create manager account",
|
"title": "Register",
|
||||||
"create": "Create account"
|
"create": "Create account"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
"langSelect": "Langue",
|
"langSelect": "Langue",
|
||||||
"logs": "Journal",
|
"logs": "Journal",
|
||||||
"project_list": "Projets",
|
"project_list": "Projets",
|
||||||
"new_project": "Nouveau projet"
|
"new_project": "Nouveau projet",
|
||||||
|
"login": "Ouvrir un session"
|
||||||
},
|
},
|
||||||
"logs": {
|
"logs": {
|
||||||
"filter": "Filtrer",
|
"filter": "Filtrer",
|
||||||
@ -21,7 +22,8 @@
|
|||||||
},
|
},
|
||||||
"projects": {
|
"projects": {
|
||||||
"projects": "Projets",
|
"projects": "Projets",
|
||||||
"dashboard": "Tableau de bord"
|
"dashboard": "Tableau de bord",
|
||||||
|
"empty": "Pas de projets"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"": "Accueil",
|
"": "Accueil",
|
||||||
@ -31,7 +33,8 @@
|
|||||||
"new_project": "Nouveau projet",
|
"new_project": "Nouveau projet",
|
||||||
"update": "Modifier",
|
"update": "Modifier",
|
||||||
"login": "Ouverture de session",
|
"login": "Ouverture de session",
|
||||||
"new_account": "Création de compte"
|
"new_account": "Création de compte",
|
||||||
|
"account": "Compte"
|
||||||
},
|
},
|
||||||
"project": {
|
"project": {
|
||||||
"name": "Nom du projet",
|
"name": "Nom du projet",
|
||||||
@ -52,14 +55,15 @@
|
|||||||
"metadata": "Métadonnés du projet"
|
"metadata": "Métadonnés du projet"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Identification - chef de projet",
|
"title": "Ouvrir un session",
|
||||||
"login": "Ouvrir un session",
|
"login": "Ouvrir un session",
|
||||||
"username": "Nom d'utilisateur",
|
"username": "Nom d'utilisateur",
|
||||||
"password": "Mot de passe",
|
"password": "Mot de passe",
|
||||||
"repeat_password": "Répéter le mot de passe"
|
"repeat_password": "Répéter le mot de passe",
|
||||||
|
"create_account": "Créer un compte"
|
||||||
},
|
},
|
||||||
"create_account": {
|
"create_account": {
|
||||||
"title": "Création d'un compte de chef de projet",
|
"title": "Créer un compte",
|
||||||
"create": "Créer un compte"
|
"create": "Créer un compte"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,3 +70,11 @@ body {
|
|||||||
max-width: 720px;
|
max-width: 720px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mat-tab-label {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-tab-body {
|
||||||
|
padding-top: 1em;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user