2018-12-24 18:45:15 +01:00
|
|
|
/*
|
2022-11-11 05:49:16 +01:00
|
|
|
* Copyright © 2018-2019, 2021 Musing Studio LLC.
|
2018-12-24 18:45:15 +01:00
|
|
|
*
|
|
|
|
* This file is part of WriteFreely.
|
|
|
|
*
|
|
|
|
* WriteFreely is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License, included
|
|
|
|
* in the LICENSE file in this source code package.
|
|
|
|
*/
|
2018-12-31 07:05:26 +01:00
|
|
|
|
2018-10-17 02:30:38 +02:00
|
|
|
package writefreely
|
|
|
|
|
|
|
|
import (
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/guregu/null/zero"
|
|
|
|
"github.com/writeas/web-core/data"
|
|
|
|
"github.com/writeas/web-core/log"
|
2021-04-06 23:24:07 +02:00
|
|
|
"github.com/writefreely/writefreely/key"
|
2018-10-17 02:30:38 +02:00
|
|
|
)
|
|
|
|
|
2019-10-25 21:04:24 +02:00
|
|
|
type UserStatus int
|
|
|
|
|
|
|
|
const (
|
|
|
|
UserActive = iota
|
2019-11-11 16:40:16 +01:00
|
|
|
UserSilenced
|
2019-10-25 21:04:24 +02:00
|
|
|
)
|
|
|
|
|
2018-10-17 02:30:38 +02:00
|
|
|
type (
|
2018-11-08 07:31:01 +01:00
|
|
|
userCredentials struct {
|
|
|
|
Alias string `json:"alias" schema:"alias"`
|
|
|
|
Pass string `json:"pass" schema:"pass"`
|
|
|
|
Email string `json:"email" schema:"email"`
|
|
|
|
Web bool `json:"web" schema:"-"`
|
|
|
|
To string `json:"-" schema:"to"`
|
|
|
|
|
|
|
|
EmailLogin bool `json:"via_email" schema:"via_email"`
|
|
|
|
}
|
|
|
|
|
|
|
|
userRegistration struct {
|
|
|
|
userCredentials
|
2019-01-18 06:05:50 +01:00
|
|
|
InviteCode string `json:"invite_code" schema:"invite_code"`
|
|
|
|
Honeypot string `json:"fullname" schema:"fullname"`
|
|
|
|
Normalize bool `json:"normalize" schema:"normalize"`
|
|
|
|
Signup bool `json:"signup" schema:"signup"`
|
2021-06-07 20:53:22 +02:00
|
|
|
|
|
|
|
// Feature fields
|
2021-06-07 21:52:24 +02:00
|
|
|
Description string `json:"description" schema:"description"`
|
|
|
|
Monetization string `json:"monetization" schema:"monetization"`
|
2018-11-08 07:31:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// AuthUser contains information for a newly authenticated user (either
|
|
|
|
// from signing up or logging in).
|
|
|
|
AuthUser struct {
|
|
|
|
AccessToken string `json:"access_token,omitempty"`
|
|
|
|
Password string `json:"password,omitempty"`
|
|
|
|
User *User `json:"user"`
|
|
|
|
|
|
|
|
// Verbose user data
|
|
|
|
Posts *[]PublicPost `json:"posts,omitempty"`
|
|
|
|
Collections *[]Collection `json:"collections,omitempty"`
|
|
|
|
}
|
|
|
|
|
2018-10-17 02:30:38 +02:00
|
|
|
// User is a consistent user object in the database and all contexts (auth
|
|
|
|
// and non-auth) in the API.
|
|
|
|
User struct {
|
|
|
|
ID int64 `json:"-"`
|
|
|
|
Username string `json:"username"`
|
|
|
|
HashedPass []byte `json:"-"`
|
|
|
|
HasPass bool `json:"has_pass"`
|
|
|
|
Email zero.String `json:"email"`
|
|
|
|
Created time.Time `json:"created"`
|
2019-10-25 21:04:24 +02:00
|
|
|
Status UserStatus `json:"status"`
|
2018-10-17 02:30:38 +02:00
|
|
|
|
|
|
|
clearEmail string `json:"email"`
|
|
|
|
}
|
2018-11-08 07:31:01 +01:00
|
|
|
|
|
|
|
userMeStats struct {
|
|
|
|
TotalCollections, TotalArticles, CollectionPosts uint64
|
|
|
|
}
|
|
|
|
|
|
|
|
ExportUser struct {
|
|
|
|
*User
|
|
|
|
Collections *[]CollectionObj `json:"collections"`
|
|
|
|
AnonymousPosts []PublicPost `json:"posts"`
|
|
|
|
}
|
|
|
|
|
|
|
|
PublicUser struct {
|
|
|
|
Username string `json:"username"`
|
|
|
|
}
|
2018-10-17 02:30:38 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
// EmailClear decrypts and returns the user's email, caching it in the user
|
|
|
|
// object.
|
2019-06-13 16:14:35 +02:00
|
|
|
func (u *User) EmailClear(keys *key.Keychain) string {
|
2018-10-17 02:30:38 +02:00
|
|
|
if u.clearEmail != "" {
|
|
|
|
return u.clearEmail
|
|
|
|
}
|
|
|
|
|
|
|
|
if u.Email.Valid && u.Email.String != "" {
|
2019-06-13 16:14:35 +02:00
|
|
|
email, err := data.Decrypt(keys.EmailKey, []byte(u.Email.String))
|
2018-10-17 02:30:38 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Error("Error decrypting user email: %v", err)
|
|
|
|
} else {
|
|
|
|
u.clearEmail = string(email)
|
|
|
|
return u.clearEmail
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
2019-01-05 04:28:29 +01:00
|
|
|
func (u User) CreatedFriendly() string {
|
|
|
|
/*
|
|
|
|
// TODO: accept a locale in this method and use that for the format
|
|
|
|
var loc monday.Locale = monday.LocaleEnUS
|
|
|
|
return monday.Format(u.Created, monday.DateTimeFormatsByLocale[loc], loc)
|
|
|
|
*/
|
|
|
|
return u.Created.Format("January 2, 2006, 3:04 PM")
|
|
|
|
}
|
|
|
|
|
2018-10-17 02:30:38 +02:00
|
|
|
// Cookie strips down an AuthUser to contain only information necessary for
|
|
|
|
// cookies.
|
|
|
|
func (u User) Cookie() *User {
|
|
|
|
u.HashedPass = []byte{}
|
|
|
|
|
|
|
|
return &u
|
|
|
|
}
|
2018-11-19 02:18:22 +01:00
|
|
|
|
|
|
|
func (u *User) IsAdmin() bool {
|
|
|
|
// TODO: get this from database
|
|
|
|
return u.ID == 1
|
|
|
|
}
|
2019-11-07 06:07:00 +01:00
|
|
|
|
2019-11-11 16:40:16 +01:00
|
|
|
func (u *User) IsSilenced() bool {
|
|
|
|
return u.Status&UserSilenced != 0
|
2019-11-07 06:07:00 +01:00
|
|
|
}
|
2021-06-22 00:24:40 +02:00
|
|
|
|
|
|
|
func (u *User) IsEmailSubscriber(app *App, collID int64) bool {
|
|
|
|
return app.db.IsEmailSubscriber("", u.ID, collID)
|
|
|
|
}
|