diff --git a/cmd/client/main.go b/cmd/client/main.go
index 3f65b16..fc8c493 100644
--- a/cmd/client/main.go
+++ b/cmd/client/main.go
@@ -8,7 +8,12 @@ import (
func main() {
http.HandleFunc("/register", handlers.RegisterFormHandler)
+ http.HandleFunc("/login", handlers.LoginHandler)
+ http.HandleFunc("/logout", handlers.LogoutHandler)
- log.Println("Сервер запущен на :8080")
+ http.HandleFunc("/dashboard", handlers.AuthMiddleware(handlers.DashboardHandler))
+
+ // Запуск сервера
+ log.Println("Клиент запущен на :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
\ No newline at end of file
diff --git a/cmd/server/main.go b/cmd/server/main.go
index 8c307bf..ef0e69e 100644
--- a/cmd/server/main.go
+++ b/cmd/server/main.go
@@ -1,16 +1,15 @@
package main
import (
- "log"
-
- "github.com/pocketbase/pocketbase"
+ "log"
+ "github.com/pocketbase/pocketbase"
)
func main() {
- app := pocketbase.New()
+ app := pocketbase.New()
- if err := app.Start(); err != nil {
- log.Fatal(err)
- }
-}
\ No newline at end of file
+ if err := app.Start(); err != nil {
+ log.Fatal(err)
+ }
+}
diff --git a/go.mod b/go.mod
index d50a44e..c031f88 100644
--- a/go.mod
+++ b/go.mod
@@ -24,14 +24,14 @@ require (
github.com/spf13/cast v1.7.1 // indirect
github.com/spf13/cobra v1.9.1 // indirect
github.com/spf13/pflag v1.0.6 // indirect
- golang.org/x/crypto v0.36.0 // indirect
+ golang.org/x/crypto v0.37.0 // indirect
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
golang.org/x/image v0.25.0 // indirect
golang.org/x/net v0.37.0 // indirect
golang.org/x/oauth2 v0.28.0 // indirect
- golang.org/x/sync v0.12.0 // indirect
- golang.org/x/sys v0.31.0 // indirect
- golang.org/x/text v0.23.0 // indirect
+ golang.org/x/sync v0.13.0 // indirect
+ golang.org/x/sys v0.32.0 // indirect
+ golang.org/x/text v0.24.0 // indirect
modernc.org/libc v1.61.13 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.8.2 // indirect
diff --git a/go.sum b/go.sum
index 1f5c15e..368df56 100644
--- a/go.sum
+++ b/go.sum
@@ -64,8 +64,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
-golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
+golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
+golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
@@ -78,16 +78,16 @@ golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
-golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
-golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
+golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
+golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
-golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
+golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
-golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
+golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
+golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
diff --git a/handlers/dashboard.go b/handlers/dashboard.go
new file mode 100644
index 0000000..f9362f7
--- /dev/null
+++ b/handlers/dashboard.go
@@ -0,0 +1,149 @@
+package handlers
+
+import (
+ "encoding/json"
+ "io"
+ "log"
+ "net/http"
+ "pocketbaseSigner/models"
+)
+
+
+func DashboardHandler(w http.ResponseWriter, r *http.Request) {
+ if r.Method != http.MethodGet {
+ http.Error(w, "Метод не поддерживается", http.StatusMethodNotAllowed)
+ return
+ }
+
+ // Получаем токен из cookie
+ cookie, err := r.Cookie("pb_auth")
+ if err != nil {
+ http.Redirect(w, r, "/login", http.StatusSeeOther)
+ return
+ }
+
+ // Получаем ID пользователя из cookie
+ userIdCookie, err := r.Cookie("user_id")
+ if err != nil {
+ log.Printf("Ошибка при получении ID пользователя: %v", err)
+ http.Redirect(w, r, "/login", http.StatusSeeOther)
+ return
+ }
+
+ // Получаем данные пользователя
+ url := "http://localhost:8090/api/collections/users/records/" + userIdCookie.Value
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ log.Printf("Ошибка при создании запроса: %v", err)
+ http.Error(w, "Внутренняя ошибка сервера", http.StatusInternalServerError)
+ return
+ }
+
+ req.Header.Set("Authorization", cookie.Value)
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ log.Printf("Ошибка при получении данных пользователя: %v", err)
+ http.Error(w, "Ошибка при получении данных", http.StatusInternalServerError)
+ return
+ }
+ defer resp.Body.Close()
+
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ log.Printf("Ошибка при чтении ответа: %v", err)
+ http.Error(w, "Ошибка при обработке данных", http.StatusInternalServerError)
+ return
+ }
+
+ // Проверяем статус ответа
+ if resp.StatusCode != http.StatusOK {
+ log.Printf("Ошибка при получении данных пользователя: %s", string(body))
+ http.Error(w, "Ошибка при получении данных пользователя", resp.StatusCode)
+ return
+ }
+
+ var userData models.UserData
+ if err := json.Unmarshal(body, &userData); err != nil {
+ log.Printf("Ошибка при разборе JSON: %v", err)
+ http.Error(w, "Ошибка при обработке данных", http.StatusInternalServerError)
+ return
+ }
+
+ // Отображаем dashboard
+ w.Header().Set("Content-Type", "text/html")
+ dashboardHTML := `
+
+
+
+
+
+ Личный кабинет
+
+
+
+
+
+
+
Информация о пользователе
+
Email: ` + userData.Email + `
+
Имя: ` + userData.FirstName + `
+
Фамилия: ` + userData.LastName + `
+
Телефон: ` + userData.Phone + `
+
Дата регистрации: ` + userData.Created + `
+
Последнее обновление: ` + userData.Updated + `
+
Статус верификации: ` + formatVerified(userData.Verified) + `
+
+
+
+
+ `
+ w.Write([]byte(dashboardHTML))
+}
+
+func formatVerified(verified bool) string {
+ if verified {
+ return "Подтвержден"
+ }
+ return "Не подтвержден"
+}
diff --git a/handlers/login.go b/handlers/login.go
new file mode 100644
index 0000000..9d89539
--- /dev/null
+++ b/handlers/login.go
@@ -0,0 +1,124 @@
+package handlers
+
+import (
+ "bytes"
+ "encoding/json"
+ "io"
+ "log"
+ "net/http"
+ "pocketbaseSigner/models"
+)
+
+//1. добавить в хэндлере регистрации переход на логин хэндлер
+//2. реализовать логин
+//3. приступить к миддлвейру
+
+
+func LoginHandler(w http.ResponseWriter, r *http.Request) {
+ if r.Method == http.MethodGet {
+ http.ServeFile(w, r, "./web/login_form.html")
+ return
+ }
+
+ if r.Method == http.MethodPost {
+ err := r.ParseForm()
+ if err != nil {
+ http.Error(w, "Ошибка при обработке формы", http.StatusBadRequest)
+ return
+ }
+
+ if r.FormValue("email") == "" || r.FormValue("password") == "" {
+ http.Error(w, "Email и пароль обязательны!", http.StatusBadRequest)
+ return
+ }
+
+ // Создаем структуру для запроса
+ loginData := map[string]string{
+ "identity": r.FormValue("email"),
+ "password": r.FormValue("password"),
+ }
+
+ // Преобразуем в JSON
+ jsonData, err := json.Marshal(loginData)
+ if err != nil {
+ log.Printf("Ошибка при создании JSON: %v", err)
+ http.Error(w, "Внутренняя ошибка сервера", http.StatusInternalServerError)
+ return
+ }
+
+ url := "http://localhost:8090/api/collections/users/auth-with-password"
+
+ req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
+ if err != nil {
+ log.Printf("Ошибка при создании запроса: %v", err)
+ http.Error(w, "Внутренняя ошибка сервера", http.StatusInternalServerError)
+ return
+ }
+
+ req.Header.Set("Content-Type", "application/json")
+
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ log.Printf("Ошибка при отправке запроса: %v", err)
+ http.Error(w, "Ошибка при подключении к серверу", http.StatusInternalServerError)
+ return
+ }
+ defer resp.Body.Close()
+
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ log.Printf("Ошибка при чтении ответа: %v", err)
+ http.Error(w, "Ошибка при обработке ответа", http.StatusInternalServerError)
+ return
+ }
+
+ // Проверяем статус ответа
+ if resp.StatusCode != http.StatusOK {
+ log.Printf("Ошибка авторизации: %s", string(body))
+ http.Error(w, "Неверный email или пароль", http.StatusUnauthorized)
+ return
+ }
+
+ // Парсим ответ для получения токена
+ var authResp models.AuthResponse
+ if err := json.Unmarshal(body, &authResp); err != nil {
+ log.Printf("Ошибка при разборе JSON: %v", err)
+ http.Error(w, "Ошибка при обработке ответа", http.StatusInternalServerError)
+ return
+ }
+
+ // Проверяем наличие токена в ответе
+ if authResp.Token == "" {
+ log.Printf("Токен отсутствует в ответе: %s", string(body))
+ http.Error(w, "Ошибка авторизации: токен не получен", http.StatusInternalServerError)
+ return
+ }
+
+ // Логируем успешную авторизацию
+ log.Printf("Успешная авторизация пользователя: %s", authResp.Token)
+
+ // Сохраняем токен в cookie
+ http.SetCookie(w, &http.Cookie{
+ Name: "pb_auth",
+ Value: authResp.Token,
+ Path: "/",
+ HttpOnly: true,
+ Secure: true,
+ SameSite: http.SameSiteStrictMode,
+ })
+
+ // Сохраняем ID пользователя в отдельную cookie
+ http.SetCookie(w, &http.Cookie{
+ Name: "user_id",
+ Value: authResp.Record.ID,
+ Path: "/",
+ HttpOnly: true,
+ Secure: true,
+ SameSite: http.SameSiteStrictMode,
+ })
+
+ // Перенаправляем на dashboard
+ http.Redirect(w, r, "/dashboard", http.StatusSeeOther)
+ }
+}
diff --git a/handlers/logout.go b/handlers/logout.go
new file mode 100644
index 0000000..6fb8a93
--- /dev/null
+++ b/handlers/logout.go
@@ -0,0 +1,31 @@
+package handlers
+
+import (
+ "net/http"
+)
+
+func LogoutHandler(w http.ResponseWriter, r *http.Request) {
+ if r.Method != http.MethodPost {
+ http.Error(w, "Метод не поддерживается", http.StatusMethodNotAllowed)
+ return
+ }
+
+ // Удаляем cookie с токеном
+ http.SetCookie(w, &http.Cookie{
+ Name: "pb_auth",
+ Value: "",
+ Path: "/",
+ MaxAge: -1,
+ })
+
+ // Удаляем cookie с ID пользователя
+ http.SetCookie(w, &http.Cookie{
+ Name: "user_id",
+ Value: "",
+ Path: "/",
+ MaxAge: -1,
+ })
+
+ // Перенаправляем на страницу логина
+ http.Redirect(w, r, "/login", http.StatusSeeOther)
+}
diff --git a/handlers/middleware.go b/handlers/middleware.go
new file mode 100644
index 0000000..861b6b1
--- /dev/null
+++ b/handlers/middleware.go
@@ -0,0 +1,45 @@
+package handlers
+
+import (
+ "log"
+ "net/http"
+)
+
+func AuthMiddleware(next http.HandlerFunc) http.HandlerFunc {
+ return func(w http.ResponseWriter, r *http.Request) {
+ // Получаем токен из cookie
+ cookie, err := r.Cookie("pb_auth")
+ if err != nil {
+ // Если токена нет, перенаправляем на страницу логина
+ http.Redirect(w, r, "/login", http.StatusSeeOther)
+ return
+ }
+
+ // Проверяем валидность токена через PocketBase
+ req, err := http.NewRequest("POST", "http://localhost:8090/api/collections/users/auth-refresh", nil)
+ if err != nil {
+ log.Printf("Ошибка при создании запроса: %v", err)
+ http.Error(w, "Внутренняя ошибка сервера", http.StatusInternalServerError)
+ return
+ }
+
+ req.Header.Set("Authorization", cookie.Value)
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ log.Printf("Ошибка при проверке токена: %v", err)
+ http.Error(w, "Ошибка при проверке авторизации", http.StatusInternalServerError)
+ return
+ }
+ defer resp.Body.Close()
+
+ // Если токен невалиден, перенаправляем на страницу логина
+ if resp.StatusCode != http.StatusOK {
+ http.Redirect(w, r, "/login", http.StatusSeeOther)
+ return
+ }
+
+ // Если токен валиден, продолжаем выполнение
+ next.ServeHTTP(w, r)
+ }
+}
diff --git a/handlers/register.go b/handlers/register.go
index 1de3ab3..32d6c7b 100644
--- a/handlers/register.go
+++ b/handlers/register.go
@@ -1,91 +1,93 @@
package handlers
import (
- "fmt"
- "log"
- "net/http"
- "pocketbaseSigner/models"
- "bytes"
- "encoding/json"
+ "bytes"
+ "encoding/json"
+ "log"
+ "net/http"
+ "pocketbaseSigner/models"
)
-
func RegisterFormHandler(w http.ResponseWriter, r *http.Request) {
- if r.Method == http.MethodGet {
- http.ServeFile(w, r, "./web/register_form.html")
- return
- }
+ if r.Method == http.MethodGet {
+ http.ServeFile(w, r, "./web/register_form.html")
+ return
+ }
- if r.Method == http.MethodPost {
- err := r.ParseForm()
- if err != nil {
- http.Error(w, "Ошибка при обработке формы", http.StatusBadRequest)
- return
- }
+ if r.Method == http.MethodPost {
+ err := r.ParseForm()
+ if err != nil {
+ http.Error(w, "Ошибка при обработке формы", http.StatusBadRequest)
+ return
+ }
- user := models.UserForm{
- Email: r.FormValue("email"),
- Password: r.FormValue("password"),
- PasswordConfirm: r.FormValue("password_confirm"),
- FirstName: r.FormValue("firstname"),
- LastName: r.FormValue("lastname"),
- Phone: r.FormValue("phone"),
- }
+ user := models.RegisterForm{
+ Email: r.FormValue("email"),
+ Password: r.FormValue("password"),
+ PasswordConfirm: r.FormValue("password_confirm"),
+ FirstName: r.FormValue("firstname"),
+ LastName: r.FormValue("lastname"),
+ Phone: r.FormValue("phone"),
+ }
- // нужно для маршалинга потому что переменные с маленькой буквы потеряются
- // если все переменные делать с большой буквы, то pocketbase не примет
- dataMap := map[string]string{
- "email": user.Email,
- "password": user.Password,
- "passwordConfirm": user.PasswordConfirm,
- "FirstName": user.FirstName,
- "LastName": user.LastName,
- "Phone": user.Phone,
- }
-
- data, err := json.Marshal(dataMap)
+ // Проверяем совпадение паролей
+ if r.FormValue("password") != r.FormValue("password_confirm") {
+ http.Error(w, "Пароли не совпали", http.StatusBadRequest)
+ return
+ }
+ // Проверяем обязательные поля
+ if user.Email == "" || user.Password == "" {
+ http.Error(w, "Email и пароль обязательны!", http.StatusBadRequest)
+ return
+ }
- if r.FormValue("password") != r.FormValue("password_confirm") {
- http.Error(w, "Пароли не совпали", http.StatusBadRequest)
- return
- }
- // Проверка
- if user.Email == "" || user.Password == "" {
- http.Error(w, "Email и пароль обязательны!", http.StatusBadRequest)
- return
- }
+ // Подготавливаем данные для отправки
+ dataMap := map[string]string{
+ "email": user.Email,
+ "password": user.Password,
+ "passwordConfirm": user.PasswordConfirm,
+ "FirstName": user.FirstName,
+ "LastName": user.LastName,
+ "Phone": user.Phone,
+ }
- log.Printf("Получен пользователь: %+v\n", user)
- fmt.Println(json.Marshal(user))
- fmt.Println()
- if err != nil {
- fmt.Println(err)
- return
- }
+ data, err := json.Marshal(dataMap)
+ if err != nil {
+ log.Printf("Ошибка при создании JSON: %v", err)
+ http.Error(w, "Внутренняя ошибка сервера", http.StatusInternalServerError)
+ return
+ }
- url:= "http://localhost:8090/api/collections/users/records"
- fmt.Println(bytes.NewBuffer(data))
- req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
- if err != nil {
- fmt.Println(err)
- return
- }
+ log.Printf("Отправляем данные пользователя: %+v\n", user)
- fmt.Println(bytes.NewBuffer(data))
- fmt.Println()
+ url := "http://localhost:8090/api/collections/users/records"
+ req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
+ if err != nil {
+ log.Printf("Ошибка при создании запроса: %v", err)
+ http.Error(w, "Внутренняя ошибка сервера", http.StatusInternalServerError)
+ return
+ }
- req.Header.Set("Content-Type", "application/json")
+ req.Header.Set("Content-Type", "application/json")
- fmt.Println(req)
- client := &http.Client{}
- resp, err := client.Do(req)
- if err != nil {
- fmt.Println(err)
- return
- }
- defer resp.Body.Close()
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ log.Printf("Ошибка при отправке запроса: %v", err)
+ http.Error(w, "Ошибка при подключении к серверу", http.StatusInternalServerError)
+ return
+ }
+ defer resp.Body.Close()
- http.Error(w, "Данные отправлены", http.StatusOK)
+ // Проверяем статус ответа
+ if resp.StatusCode != http.StatusOK {
+ log.Printf("Ошибка при регистрации: %v", resp.StatusCode)
+ http.Error(w, "Ошибка при регистрации", resp.StatusCode)
+ return
+ }
+
+ // Перенаправляем на страницу логина после успешной регистрации
+ http.Redirect(w, r, "/login", http.StatusSeeOther)
+ }
}
-}
\ No newline at end of file
diff --git a/models/auth.go b/models/auth.go
new file mode 100644
index 0000000..2e87355
--- /dev/null
+++ b/models/auth.go
@@ -0,0 +1,12 @@
+package models
+
+type AuthResponse struct {
+ Record struct {
+ ID string `json:"id"`
+ Email string `json:"email"`
+ FirstName string `json:"FirstName"`
+ LastName string `json:"LastName"`
+ Phone string `json:"Phone"`
+ } `json:"record"`
+ Token string `json:"token"`
+}
\ No newline at end of file
diff --git a/models/forms.go b/models/forms.go
new file mode 100644
index 0000000..fdb4daa
--- /dev/null
+++ b/models/forms.go
@@ -0,0 +1,15 @@
+package models
+
+type RegisterForm struct {
+ Email string
+ Password string
+ PasswordConfirm string
+ FirstName string
+ LastName string
+ Phone string
+}
+
+type LoginForm struct{
+ Email string
+ Password string
+}
\ No newline at end of file
diff --git a/models/user.go b/models/user.go
index c5216c1..f5e8d9d 100644
--- a/models/user.go
+++ b/models/user.go
@@ -1,17 +1,24 @@
package models
-type UserForm struct {
- Email string
- Password string
- PasswordConfirm string
- FirstName string
- LastName string
- Phone string
-}
type UserResponse struct {
ID string `json:"id"`
Email string `json:"email"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
+}
+
+type UserData struct {
+ CollectionId string `json:"collectionId"`
+ CollectionName string `json:"collectionName"`
+ ID string `json:"id"`
+ Email string `json:"email"`
+ FirstName string `json:"FirstName"`
+ LastName string `json:"LastName"`
+ Phone string `json:"Phone"`
+ EmailVisibility bool `json:"emailVisibility"`
+ Verified bool `json:"verified"`
+ Avatar string `json:"avatar"`
+ Created string `json:"created"`
+ Updated string `json:"updated"`
}
\ No newline at end of file
diff --git a/pb_data/auxiliary.db b/pb_data/auxiliary.db
index 7ddd33f..e86746f 100644
Binary files a/pb_data/auxiliary.db and b/pb_data/auxiliary.db differ
diff --git a/pb_data/data.db b/pb_data/data.db
index 6828647..f5beb1f 100644
Binary files a/pb_data/data.db and b/pb_data/data.db differ
diff --git a/web/login_form.html b/web/login_form.html
new file mode 100644
index 0000000..9bbcec9
--- /dev/null
+++ b/web/login_form.html
@@ -0,0 +1,84 @@
+
+
+
+
+
+ Регистрация / Авторизация
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/register_form.html b/web/register_form.html
index 22dc18e..023df90 100644
--- a/web/register_form.html
+++ b/web/register_form.html
@@ -96,7 +96,11 @@
-
+
+
+
+