Auth: Add page to change password.

Configure launcher as a default return to address.

Use standard X-Forwarded-User instead of custom X-User header.
Add X-Forwarded-UserId header holding user unique identificator.

Change-Id: Ib2e6329ba9fb91d2cc9a86b0c5fc78898769e3b8
diff --git a/core/installer/welcome/welcome.go b/core/installer/welcome/welcome.go
index b6436c7..7aa6d3a 100644
--- a/core/installer/welcome/welcome.go
+++ b/core/installer/welcome/welcome.go
@@ -18,11 +18,8 @@
 	"github.com/giolekva/pcloud/core/installer/soft"
 )
 
-//go:embed create-account.html
-var indexHtml []byte
-
-//go:embed create-account-success.html
-var successHtml []byte
+//go:embed welcome-tmpl/*
+var welcomeTmpls embed.FS
 
 //go:embed static/*
 var staticAssets embed.FS
@@ -30,6 +27,34 @@
 //go:embed stat/*
 var statAssets embed.FS
 
+type welcomeTmplts struct {
+	createAccount        *template.Template
+	createAccountSuccess *template.Template
+}
+
+func parseTemplatesWelcome(fs embed.FS) (welcomeTmplts, error) {
+	base, err := template.New("base.html").ParseFS(fs, "welcome-tmpl/base.html")
+	if err != nil {
+		return welcomeTmplts{}, err
+	}
+	parse := func(path string) (*template.Template, error) {
+		if b, err := base.Clone(); err != nil {
+			return nil, err
+		} else {
+			return b.ParseFS(fs, path)
+		}
+	}
+	createAccount, err := parse("welcome-tmpl/create-account.html")
+	if err != nil {
+		return welcomeTmplts{}, err
+	}
+	createAccountSuccess, err := parse("welcome-tmpl/create-account-success.html")
+	if err != nil {
+		return welcomeTmplts{}, err
+	}
+	return welcomeTmplts{createAccount, createAccountSuccess}, nil
+}
+
 type Server struct {
 	port              int
 	repo              soft.RepoIO
@@ -38,6 +63,7 @@
 	createAccountAddr string
 	loginAddr         string
 	membershipsAddr   string
+	tmpl              welcomeTmplts
 }
 
 func NewServer(
@@ -48,7 +74,11 @@
 	createAccountAddr string,
 	loginAddr string,
 	membershipsAddr string,
-) *Server {
+) (*Server, error) {
+	tmplts, err := parseTemplatesWelcome(welcomeTmpls)
+	if err != nil {
+		return nil, err
+	}
 	return &Server{
 		port,
 		repo,
@@ -57,7 +87,8 @@
 		createAccountAddr,
 		loginAddr,
 		membershipsAddr,
-	}
+		tmplts,
+	}, nil
 }
 
 func (s *Server) Start() {
@@ -70,7 +101,7 @@
 }
 
 func (s *Server) createAccountForm(w http.ResponseWriter, r *http.Request) {
-	renderRegistrationForm(w, formData{})
+	s.renderRegistrationForm(w, formData{})
 }
 
 type formData struct {
@@ -79,6 +110,12 @@
 	Data           createAccountReq
 }
 
+type cpFormData struct {
+	UsernameErrors []string
+	PasswordErrors []string
+	Password       string
+}
+
 type createAccountReq struct {
 	Username    string `json:"username,omitempty"`
 	Password    string `json:"password,omitempty"`
@@ -132,30 +169,20 @@
 	return req, nil
 }
 
-func renderRegistrationForm(w http.ResponseWriter, data formData) {
-	tmpl, err := template.New("create-account").Parse(string(indexHtml))
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
-	if err := tmpl.Execute(w, data); err != nil {
+func (s *Server) renderRegistrationForm(w http.ResponseWriter, data formData) {
+	if err := s.tmpl.createAccount.Execute(w, data); err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
 }
 
-func renderRegistrationSuccess(w http.ResponseWriter, loginAddr string) {
+func (s *Server) renderRegistrationSuccess(w http.ResponseWriter, loginAddr string) {
 	data := struct {
 		LoginAddr string
 	}{
 		LoginAddr: loginAddr,
 	}
-	tmpl, err := template.New("create-account-success").Parse(string(successHtml))
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
-	if err := tmpl.Execute(w, data); err != nil {
+	if err := s.tmpl.createAccountSuccess.Execute(w, data); err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
@@ -200,7 +227,7 @@
 					passwordErrors = append(passwordErrors, err.Message)
 				}
 			}
-			renderRegistrationForm(w, formData{
+			s.renderRegistrationForm(w, formData{
 				usernameErrors,
 				passwordErrors,
 				req,
@@ -212,7 +239,7 @@
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	renderRegistrationSuccess(w, s.loginAddr)
+	s.renderRegistrationSuccess(w, s.loginAddr)
 }
 
 type firstAccount struct {