feat: implement user profile management with avatars, login, and personal data
- Add avatar upload functionality with public URL access. - Implement user login with email and password authentication. - Create endpoints for fetching and updating the authenticated user's profile. - Set up database migrations for user profiles, including email and role management. - Introduce personal data management linked to user profiles. - Add email verification process with welcome email templates.
This commit is contained in:
54
profiles/avatars.go
Normal file
54
profiles/avatars.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package profiles
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"encore.dev/beta/errs"
|
||||
"encore.dev/storage/objects"
|
||||
"encore.dev/types/uuid"
|
||||
)
|
||||
|
||||
// avatars stores user avatar images. It is public so the returned URLs can be
|
||||
// rendered directly by browsers without authentication.
|
||||
var avatars = objects.NewBucket("avatars", objects.BucketConfig{
|
||||
Public: true,
|
||||
})
|
||||
|
||||
type uploadAvatarResponse struct {
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
// UploadAvatar stores the request body as a new avatar image and returns its
|
||||
// public URL. The caller is expected to persist the URL via the profile
|
||||
// endpoints. Each upload gets a fresh key, so re-uploading never overwrites.
|
||||
//
|
||||
//encore:api auth raw method=POST path=/profiles/avatar
|
||||
func UploadAvatar(w http.ResponseWriter, req *http.Request) {
|
||||
key, err := uuid.NewV4()
|
||||
if err != nil {
|
||||
errs.HTTPError(w, errs.WrapCode(err, errs.Internal, "failed to generate avatar key"))
|
||||
return
|
||||
}
|
||||
|
||||
contentType := req.Header.Get("Content-Type")
|
||||
if contentType == "" {
|
||||
contentType = "application/octet-stream"
|
||||
}
|
||||
|
||||
writer := avatars.Upload(req.Context(), key.String(),
|
||||
objects.WithUploadAttrs(objects.UploadAttrs{ContentType: contentType}))
|
||||
if _, err := io.Copy(writer, req.Body); err != nil {
|
||||
writer.Abort(err)
|
||||
errs.HTTPError(w, errs.WrapCode(err, errs.Internal, "failed to upload avatar"))
|
||||
return
|
||||
}
|
||||
if err := writer.Close(); err != nil {
|
||||
errs.HTTPError(w, errs.WrapCode(err, errs.Internal, "failed to store avatar"))
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_ = json.NewEncoder(w).Encode(uploadAvatarResponse{URL: avatars.PublicURL(key.String()).String()})
|
||||
}
|
||||
Reference in New Issue
Block a user