ResetPassword Table and all CRUD methods. (#1916)
This commit is contained in:
parent
7ce9a60c85
commit
f46487b015
@ -8,6 +8,8 @@ const (
|
|||||||
ActivationPath = "activationPath"
|
ActivationPath = "activationPath"
|
||||||
// PasswordRecoveryPath is key for path which handles password recovery
|
// PasswordRecoveryPath is key for path which handles password recovery
|
||||||
PasswordRecoveryPath = "passwordRecoveryPath"
|
PasswordRecoveryPath = "passwordRecoveryPath"
|
||||||
|
// CancelPasswordRecoveryPath is key for path which handles let us know sequence
|
||||||
|
CancelPasswordRecoveryPath = "cancelPasswordRecoveryPath"
|
||||||
// SignInPath is key for sign in server route
|
// SignInPath is key for sign in server route
|
||||||
SignInPath = "signInPath"
|
SignInPath = "signInPath"
|
||||||
)
|
)
|
||||||
@ -26,9 +28,10 @@ func (*AccountActivationEmail) Subject() string { return "Activate your email" }
|
|||||||
|
|
||||||
// ForgotPasswordEmail is mailservice template with reset password data
|
// ForgotPasswordEmail is mailservice template with reset password data
|
||||||
type ForgotPasswordEmail struct {
|
type ForgotPasswordEmail struct {
|
||||||
Origin string
|
Origin string
|
||||||
UserName string
|
UserName string
|
||||||
ResetLink string
|
ResetLink string
|
||||||
|
CancelPasswordRecoveryLink string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Template returns email template name
|
// Template returns email template name
|
||||||
|
@ -112,14 +112,15 @@ func rootQuery(service *console.Service, mailService *mailservice.Service, types
|
|||||||
return false, fmt.Errorf("%s is not found", email)
|
return false, fmt.Errorf("%s is not found", email)
|
||||||
}
|
}
|
||||||
|
|
||||||
recoveryToken, err := service.GeneratePasswordRecoveryToken(p.Context, user.ID, user.Email)
|
recoveryToken, err := service.GeneratePasswordRecoveryToken(p.Context, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, errors.New("failed to generate password recovery token")
|
return false, errors.New("failed to generate password recovery token")
|
||||||
}
|
}
|
||||||
|
|
||||||
rootObject := p.Info.RootValue.(map[string]interface{})
|
rootObject := p.Info.RootValue.(map[string]interface{})
|
||||||
origin := rootObject["origin"].(string)
|
origin := rootObject["origin"].(string)
|
||||||
link := origin + rootObject[PasswordRecoveryPath].(string) + recoveryToken
|
passwordRecoveryLink := origin + rootObject[PasswordRecoveryPath].(string) + recoveryToken
|
||||||
|
cancelPasswordRecoveryLink := origin + rootObject[CancelPasswordRecoveryPath].(string) + recoveryToken
|
||||||
userName := user.ShortName
|
userName := user.ShortName
|
||||||
if user.ShortName == "" {
|
if user.ShortName == "" {
|
||||||
userName = user.FullName
|
userName = user.FullName
|
||||||
@ -131,9 +132,10 @@ func rootQuery(service *console.Service, mailService *mailservice.Service, types
|
|||||||
p.Context,
|
p.Context,
|
||||||
[]post.Address{{Address: user.Email, Name: userName}},
|
[]post.Address{{Address: user.Email, Name: userName}},
|
||||||
&ForgotPasswordEmail{
|
&ForgotPasswordEmail{
|
||||||
Origin: origin,
|
Origin: origin,
|
||||||
ResetLink: link,
|
ResetLink: passwordRecoveryLink,
|
||||||
UserName: userName,
|
CancelPasswordRecoveryLink: cancelPasswordRecoveryLink,
|
||||||
|
UserName: userName,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}()
|
}()
|
||||||
|
@ -502,7 +502,8 @@ func TestGraphqlQuery(t *testing.T) {
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
rootObject[consoleql.PasswordRecoveryPath] = "?activationToken="
|
rootObject[consoleql.PasswordRecoveryPath] = "?token="
|
||||||
|
rootObject[consoleql.CancelPasswordRecoveryPath] = "?token="
|
||||||
query := fmt.Sprintf("query {forgotPassword(email: \"%s\")}", user.Email)
|
query := fmt.Sprintf("query {forgotPassword(email: \"%s\")}", user.Email)
|
||||||
|
|
||||||
result := testQuery(t, query)
|
result := testQuery(t, query)
|
||||||
|
@ -94,6 +94,7 @@ func NewServer(logger *zap.Logger, config Config, service *console.Service, mail
|
|||||||
if server.config.StaticDir != "" {
|
if server.config.StaticDir != "" {
|
||||||
mux.Handle("/activation/", http.HandlerFunc(server.accountActivationHandler))
|
mux.Handle("/activation/", http.HandlerFunc(server.accountActivationHandler))
|
||||||
mux.Handle("/password-recovery/", http.HandlerFunc(server.passwordRecoveryHandler))
|
mux.Handle("/password-recovery/", http.HandlerFunc(server.passwordRecoveryHandler))
|
||||||
|
mux.Handle("/cancel-password-recovery/", http.HandlerFunc(server.cancelPasswordRecoveryHandler))
|
||||||
mux.Handle("/registrationToken/", http.HandlerFunc(server.createRegistrationTokenHandler))
|
mux.Handle("/registrationToken/", http.HandlerFunc(server.createRegistrationTokenHandler))
|
||||||
mux.Handle("/usage-report/", http.HandlerFunc(server.bucketUsageReportHandler))
|
mux.Handle("/usage-report/", http.HandlerFunc(server.bucketUsageReportHandler))
|
||||||
mux.Handle("/static/", http.StripPrefix("/static", fs))
|
mux.Handle("/static/", http.StripPrefix("/static", fs))
|
||||||
@ -251,22 +252,27 @@ func (s *Server) passwordRecoveryHandler(w http.ResponseWriter, req *http.Reques
|
|||||||
err := req.ParseForm()
|
err := req.ParseForm()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.serveError(w, req)
|
s.serveError(w, req)
|
||||||
|
s.log.Debug(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
password := req.FormValue("password")
|
password := req.FormValue("password")
|
||||||
passwordRepeat := req.FormValue("passwordRepeat")
|
passwordRepeat := req.FormValue("passwordRepeat")
|
||||||
if strings.Compare(password, passwordRepeat) != 0 {
|
if strings.Compare(password, passwordRepeat) != 0 {
|
||||||
s.serveError(w, req)
|
s.serveError(w, req)
|
||||||
|
s.log.Debug(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.service.ResetPassword(context.Background(), recoveryToken, password)
|
err = s.service.ResetPassword(context.Background(), recoveryToken, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
s.log.Debug(err.Error())
|
||||||
s.serveError(w, req)
|
s.serveError(w, req)
|
||||||
}
|
}
|
||||||
|
http.ServeFile(w, req, filepath.Join(s.config.StaticDir, "static", "resetPassword", "success.html"))
|
||||||
default:
|
default:
|
||||||
t, err := template.ParseFiles(filepath.Join(s.config.StaticDir, "static", "resetPassword", "resetPassword.html"))
|
t, err := template.ParseFiles(filepath.Join(s.config.StaticDir, "static", "resetPassword", "resetPassword.html"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
s.log.Debug(err.Error())
|
||||||
s.serveError(w, req)
|
s.serveError(w, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,6 +283,18 @@ func (s *Server) passwordRecoveryHandler(w http.ResponseWriter, req *http.Reques
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) cancelPasswordRecoveryHandler(w http.ResponseWriter, req *http.Request) {
|
||||||
|
recoveryToken := req.URL.Query().Get("token")
|
||||||
|
if len(recoveryToken) == 0 {
|
||||||
|
http.Redirect(w, req, "https://storjlabs.atlassian.net/servicedesk/customer/portals", http.StatusSeeOther)
|
||||||
|
}
|
||||||
|
|
||||||
|
// No need to check error as we anyway redirect user to support page
|
||||||
|
_ = s.service.RevokeResetPasswordToken(context.Background(), recoveryToken)
|
||||||
|
|
||||||
|
http.Redirect(w, req, "https://storjlabs.atlassian.net/servicedesk/customer/portals", http.StatusSeeOther)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) serveError(w http.ResponseWriter, req *http.Request) {
|
func (s *Server) serveError(w http.ResponseWriter, req *http.Request) {
|
||||||
http.ServeFile(w, req, filepath.Join(s.config.StaticDir, "static", "errors", "404.html"))
|
http.ServeFile(w, req, filepath.Join(s.config.StaticDir, "static", "errors", "404.html"))
|
||||||
}
|
}
|
||||||
@ -305,6 +323,7 @@ func (s *Server) grapqlHandler(w http.ResponseWriter, req *http.Request) {
|
|||||||
rootObject["origin"] = s.config.ExternalAddress
|
rootObject["origin"] = s.config.ExternalAddress
|
||||||
rootObject[consoleql.ActivationPath] = "activation/?token="
|
rootObject[consoleql.ActivationPath] = "activation/?token="
|
||||||
rootObject[consoleql.PasswordRecoveryPath] = "password-recovery/?token="
|
rootObject[consoleql.PasswordRecoveryPath] = "password-recovery/?token="
|
||||||
|
rootObject[consoleql.CancelPasswordRecoveryPath] = "cancel-password-recovery/?token="
|
||||||
rootObject[consoleql.SignInPath] = "login"
|
rootObject[consoleql.SignInPath] = "login"
|
||||||
|
|
||||||
result := graphql.Do(graphql.Params{
|
result := graphql.Do(graphql.Params{
|
||||||
|
@ -23,6 +23,8 @@ type DB interface {
|
|||||||
BucketUsage() accounting.BucketUsage
|
BucketUsage() accounting.BucketUsage
|
||||||
// RegistrationTokens is a getter for RegistrationTokens repository
|
// RegistrationTokens is a getter for RegistrationTokens repository
|
||||||
RegistrationTokens() RegistrationTokens
|
RegistrationTokens() RegistrationTokens
|
||||||
|
// ResetPasswordTokens is a getter for ResetPasswordTokens repository
|
||||||
|
ResetPasswordTokens() ResetPasswordTokens
|
||||||
// UsageRollups is a getter for UsageRollups repository
|
// UsageRollups is a getter for UsageRollups repository
|
||||||
UsageRollups() UsageRollups
|
UsageRollups() UsageRollups
|
||||||
|
|
||||||
|
70
satellite/console/resetpasswordtoken.go
Normal file
70
satellite/console/resetpasswordtoken.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// Copyright (C) 2018 Storj Labs, Inc.
|
||||||
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
|
package console
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/base64"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/skyrings/skyring-common/tools/uuid"
|
||||||
|
"github.com/zeebo/errs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ResetPasswordTokens is interface for working with reset password tokens
|
||||||
|
type ResetPasswordTokens interface {
|
||||||
|
// Create creates new reset password token
|
||||||
|
Create(ctx context.Context, ownerID uuid.UUID) (*ResetPasswordToken, error)
|
||||||
|
// GetBySecret retrieves ResetPasswordToken with given secret
|
||||||
|
GetBySecret(ctx context.Context, secret ResetPasswordSecret) (*ResetPasswordToken, error)
|
||||||
|
// GetByOwnerID retrieves ResetPasswordToken by ownerID
|
||||||
|
GetByOwnerID(ctx context.Context, ownerID uuid.UUID) (*ResetPasswordToken, error)
|
||||||
|
// Delete deletes ResetPasswordToken by ResetPasswordSecret
|
||||||
|
Delete(ctx context.Context, secret ResetPasswordSecret) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetPasswordSecret stores secret of registration token
|
||||||
|
type ResetPasswordSecret [32]byte
|
||||||
|
|
||||||
|
// ResetPasswordToken describing reset password model in the database
|
||||||
|
type ResetPasswordToken struct {
|
||||||
|
// Secret is PK of the table and keeps unique value for reset password token
|
||||||
|
Secret ResetPasswordSecret
|
||||||
|
// OwnerID stores current token owner ID
|
||||||
|
OwnerID *uuid.UUID
|
||||||
|
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewResetPasswordSecret creates new reset password secret
|
||||||
|
func NewResetPasswordSecret() (ResetPasswordSecret, error) {
|
||||||
|
var b [32]byte
|
||||||
|
|
||||||
|
_, err := rand.Read(b[:])
|
||||||
|
if err != nil {
|
||||||
|
return b, errs.New("error creating registration secret")
|
||||||
|
}
|
||||||
|
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements Stringer
|
||||||
|
func (secret ResetPasswordSecret) String() string {
|
||||||
|
return base64.URLEncoding.EncodeToString(secret[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetPasswordSecretFromBase64 creates new reset password secret from base64 string
|
||||||
|
func ResetPasswordSecretFromBase64(s string) (ResetPasswordSecret, error) {
|
||||||
|
var secret ResetPasswordSecret
|
||||||
|
|
||||||
|
b, err := base64.URLEncoding.DecodeString(s)
|
||||||
|
if err != nil {
|
||||||
|
return secret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
copy(secret[:], b)
|
||||||
|
|
||||||
|
return secret, nil
|
||||||
|
}
|
89
satellite/console/resetpasswordtoken_test.go
Normal file
89
satellite/console/resetpasswordtoken_test.go
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// Copyright (C) 2019 Storj Labs, Inc.
|
||||||
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
|
package console_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"storj.io/storj/internal/testcontext"
|
||||||
|
"storj.io/storj/satellite"
|
||||||
|
"storj.io/storj/satellite/console"
|
||||||
|
"storj.io/storj/satellite/satellitedb/satellitedbtest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewRegistrationSecret(t *testing.T) {
|
||||||
|
// testing constants
|
||||||
|
const (
|
||||||
|
// for user
|
||||||
|
shortName = "lastName"
|
||||||
|
email = "email@ukr.net"
|
||||||
|
pass = "123456"
|
||||||
|
userFullName = "name"
|
||||||
|
)
|
||||||
|
|
||||||
|
satellitedbtest.Run(t, func(t *testing.T, db satellite.DB) {
|
||||||
|
ctx := testcontext.New(t)
|
||||||
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
|
users := db.Console().Users()
|
||||||
|
rptokens := db.Console().ResetPasswordTokens()
|
||||||
|
|
||||||
|
var owner *console.User
|
||||||
|
var rptoken *console.ResetPasswordToken
|
||||||
|
|
||||||
|
t.Run("Insert reset password token successfully", func(t *testing.T) {
|
||||||
|
var err error
|
||||||
|
owner, err = users.Insert(ctx, &console.User{
|
||||||
|
FullName: userFullName,
|
||||||
|
ShortName: shortName,
|
||||||
|
Email: email,
|
||||||
|
PasswordHash: []byte(pass),
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, owner)
|
||||||
|
|
||||||
|
rptoken, err = rptokens.Create(ctx, owner.ID)
|
||||||
|
assert.NotNil(t, rptoken)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Get reset password token successfully", func(t *testing.T) {
|
||||||
|
tokenBySecret, err := rptokens.GetBySecret(ctx, rptoken.Secret)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, rptoken.Secret, tokenBySecret.Secret)
|
||||||
|
assert.Equal(t, rptoken.CreatedAt, tokenBySecret.CreatedAt)
|
||||||
|
assert.Equal(t, rptoken.OwnerID, tokenBySecret.OwnerID)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Get reset password token by UUID and Secret equal", func(t *testing.T) {
|
||||||
|
tokenBySecret, err := rptokens.GetBySecret(ctx, rptoken.Secret)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
tokenByUUID, err := rptokens.GetByOwnerID(ctx, *rptoken.OwnerID)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, tokenByUUID.Secret, tokenBySecret.Secret)
|
||||||
|
assert.Equal(t, tokenByUUID.CreatedAt, tokenBySecret.CreatedAt)
|
||||||
|
assert.Equal(t, tokenByUUID.OwnerID, tokenBySecret.OwnerID)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Successful base64 encoding", func(t *testing.T) {
|
||||||
|
base64token := rptoken.Secret.String()
|
||||||
|
assert.NotEmpty(t, base64token)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Successful base64 decoding", func(t *testing.T) {
|
||||||
|
base64token := rptoken.Secret.String()
|
||||||
|
assert.NotEmpty(t, base64token)
|
||||||
|
|
||||||
|
secretFromString, err := console.ResetPasswordSecretFromBase64(base64token)
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, rptoken.Secret, secretFromString)
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
@ -151,16 +151,23 @@ func (s *Service) GenerateActivationToken(ctx context.Context, id uuid.UUID, ema
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GeneratePasswordRecoveryToken - is a method for generating password recovery token
|
// GeneratePasswordRecoveryToken - is a method for generating password recovery token
|
||||||
func (s *Service) GeneratePasswordRecoveryToken(ctx context.Context, id uuid.UUID, email string) (token string, err error) {
|
func (s *Service) GeneratePasswordRecoveryToken(ctx context.Context, id uuid.UUID) (token string, err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
claims := &consoleauth.Claims{
|
resetPasswordToken, err := s.store.ResetPasswordTokens().GetByOwnerID(ctx, id)
|
||||||
ID: id,
|
if err == nil {
|
||||||
Email: email,
|
err := s.store.ResetPasswordTokens().Delete(ctx, resetPasswordToken.Secret)
|
||||||
Expiration: time.Now().Add(time.Hour),
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.createToken(claims)
|
resetPasswordToken, err = s.store.ResetPasswordTokens().Create(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resetPasswordToken.Secret.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActivateAccount - is a method for activating user account after registration
|
// ActivateAccount - is a method for activating user account after registration
|
||||||
@ -211,17 +218,16 @@ func (s *Service) ActivateAccount(ctx context.Context, activationToken string) (
|
|||||||
func (s *Service) ResetPassword(ctx context.Context, resetPasswordToken, password string) (err error) {
|
func (s *Service) ResetPassword(ctx context.Context, resetPasswordToken, password string) (err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
token, err := consoleauth.FromBase64URLString(resetPasswordToken)
|
secret, err := ResetPasswordSecretFromBase64(resetPasswordToken)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
token, err := s.store.ResetPasswordTokens().GetBySecret(ctx, secret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
claims, err := s.authenticate(token)
|
user, err := s.store.Users().Get(ctx, *token.OwnerID)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
user, err := s.store.Users().Get(ctx, claims.ID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -230,7 +236,7 @@ func (s *Service) ResetPassword(ctx context.Context, resetPasswordToken, passwor
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if time.Since(claims.Expiration) > 0 {
|
if time.Since(token.CreatedAt) > tokenExpirationTime {
|
||||||
return errs.New(passwordRecoveryTokenIsExpiredErrMsg)
|
return errs.New(passwordRecoveryTokenIsExpiredErrMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +246,25 @@ func (s *Service) ResetPassword(ctx context.Context, resetPasswordToken, passwor
|
|||||||
}
|
}
|
||||||
|
|
||||||
user.PasswordHash = hash
|
user.PasswordHash = hash
|
||||||
return s.store.Users().Update(ctx, user)
|
|
||||||
|
err = s.store.Users().Update(ctx, user)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.store.ResetPasswordTokens().Delete(ctx, token.Secret)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RevokeResetPasswordToken - is a method to revoke reset password token
|
||||||
|
func (s *Service) RevokeResetPasswordToken(ctx context.Context, resetPasswordToken string) (err error) {
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
|
secret, err := ResetPasswordSecretFromBase64(resetPasswordToken)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.store.ResetPasswordTokens().Delete(ctx, secret)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Token authenticates User by credentials and returns auth token
|
// Token authenticates User by credentials and returns auth token
|
||||||
|
@ -51,6 +51,11 @@ func (db *ConsoleDB) RegistrationTokens() console.RegistrationTokens {
|
|||||||
return ®istrationTokens{db.methods}
|
return ®istrationTokens{db.methods}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResetPasswordTokens is a getter for ResetPasswordTokens repository
|
||||||
|
func (db *ConsoleDB) ResetPasswordTokens() console.ResetPasswordTokens {
|
||||||
|
return &resetPasswordTokens{db.methods}
|
||||||
|
}
|
||||||
|
|
||||||
// UsageRollups is a getter for console.UsageRollups repository
|
// UsageRollups is a getter for console.UsageRollups repository
|
||||||
func (db *ConsoleDB) UsageRollups() console.UsageRollups {
|
func (db *ConsoleDB) UsageRollups() console.UsageRollups {
|
||||||
return &usagerollups{db.db}
|
return &usagerollups{db.db}
|
||||||
|
@ -519,3 +519,26 @@ read one (
|
|||||||
where registration_token.owner_id = ?
|
where registration_token.owner_id = ?
|
||||||
)
|
)
|
||||||
update registration_token ( where registration_token.secret = ? )
|
update registration_token ( where registration_token.secret = ? )
|
||||||
|
|
||||||
|
//--- satellite reset password token ---//
|
||||||
|
|
||||||
|
model reset_password_token (
|
||||||
|
key secret
|
||||||
|
unique owner_id
|
||||||
|
|
||||||
|
field secret blob
|
||||||
|
field owner_id blob ( updatable )
|
||||||
|
|
||||||
|
field created_at timestamp ( autoinsert )
|
||||||
|
)
|
||||||
|
|
||||||
|
create reset_password_token ( )
|
||||||
|
read one (
|
||||||
|
select reset_password_token
|
||||||
|
where reset_password_token.secret = ?
|
||||||
|
)
|
||||||
|
read one (
|
||||||
|
select reset_password_token
|
||||||
|
where reset_password_token.owner_id = ?
|
||||||
|
)
|
||||||
|
delete reset_password_token ( where reset_password_token.secret = ? )
|
||||||
|
@ -400,6 +400,13 @@ CREATE TABLE registration_tokens (
|
|||||||
PRIMARY KEY ( secret ),
|
PRIMARY KEY ( secret ),
|
||||||
UNIQUE ( owner_id )
|
UNIQUE ( owner_id )
|
||||||
);
|
);
|
||||||
|
CREATE TABLE reset_password_tokens (
|
||||||
|
secret bytea NOT NULL,
|
||||||
|
owner_id bytea NOT NULL,
|
||||||
|
created_at timestamp with time zone NOT NULL,
|
||||||
|
PRIMARY KEY ( secret ),
|
||||||
|
UNIQUE ( owner_id )
|
||||||
|
);
|
||||||
CREATE TABLE serial_numbers (
|
CREATE TABLE serial_numbers (
|
||||||
id serial NOT NULL,
|
id serial NOT NULL,
|
||||||
serial_number bytea NOT NULL,
|
serial_number bytea NOT NULL,
|
||||||
@ -650,6 +657,13 @@ CREATE TABLE registration_tokens (
|
|||||||
PRIMARY KEY ( secret ),
|
PRIMARY KEY ( secret ),
|
||||||
UNIQUE ( owner_id )
|
UNIQUE ( owner_id )
|
||||||
);
|
);
|
||||||
|
CREATE TABLE reset_password_tokens (
|
||||||
|
secret BLOB NOT NULL,
|
||||||
|
owner_id BLOB NOT NULL,
|
||||||
|
created_at TIMESTAMP NOT NULL,
|
||||||
|
PRIMARY KEY ( secret ),
|
||||||
|
UNIQUE ( owner_id )
|
||||||
|
);
|
||||||
CREATE TABLE serial_numbers (
|
CREATE TABLE serial_numbers (
|
||||||
id INTEGER NOT NULL,
|
id INTEGER NOT NULL,
|
||||||
serial_number BLOB NOT NULL,
|
serial_number BLOB NOT NULL,
|
||||||
@ -2757,6 +2771,75 @@ func (f RegistrationToken_CreatedAt_Field) value() interface{} {
|
|||||||
|
|
||||||
func (RegistrationToken_CreatedAt_Field) _Column() string { return "created_at" }
|
func (RegistrationToken_CreatedAt_Field) _Column() string { return "created_at" }
|
||||||
|
|
||||||
|
type ResetPasswordToken struct {
|
||||||
|
Secret []byte
|
||||||
|
OwnerId []byte
|
||||||
|
CreatedAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ResetPasswordToken) _Table() string { return "reset_password_tokens" }
|
||||||
|
|
||||||
|
type ResetPasswordToken_Update_Fields struct {
|
||||||
|
OwnerId ResetPasswordToken_OwnerId_Field
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResetPasswordToken_Secret_Field struct {
|
||||||
|
_set bool
|
||||||
|
_null bool
|
||||||
|
_value []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResetPasswordToken_Secret(v []byte) ResetPasswordToken_Secret_Field {
|
||||||
|
return ResetPasswordToken_Secret_Field{_set: true, _value: v}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f ResetPasswordToken_Secret_Field) value() interface{} {
|
||||||
|
if !f._set || f._null {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return f._value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ResetPasswordToken_Secret_Field) _Column() string { return "secret" }
|
||||||
|
|
||||||
|
type ResetPasswordToken_OwnerId_Field struct {
|
||||||
|
_set bool
|
||||||
|
_null bool
|
||||||
|
_value []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResetPasswordToken_OwnerId(v []byte) ResetPasswordToken_OwnerId_Field {
|
||||||
|
return ResetPasswordToken_OwnerId_Field{_set: true, _value: v}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f ResetPasswordToken_OwnerId_Field) value() interface{} {
|
||||||
|
if !f._set || f._null {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return f._value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ResetPasswordToken_OwnerId_Field) _Column() string { return "owner_id" }
|
||||||
|
|
||||||
|
type ResetPasswordToken_CreatedAt_Field struct {
|
||||||
|
_set bool
|
||||||
|
_null bool
|
||||||
|
_value time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResetPasswordToken_CreatedAt(v time.Time) ResetPasswordToken_CreatedAt_Field {
|
||||||
|
return ResetPasswordToken_CreatedAt_Field{_set: true, _value: v}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f ResetPasswordToken_CreatedAt_Field) value() interface{} {
|
||||||
|
if !f._set || f._null {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return f._value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ResetPasswordToken_CreatedAt_Field) _Column() string { return "created_at" }
|
||||||
|
|
||||||
type SerialNumber struct {
|
type SerialNumber struct {
|
||||||
Id int
|
Id int
|
||||||
SerialNumber []byte
|
SerialNumber []byte
|
||||||
@ -4132,6 +4215,30 @@ func (obj *postgresImpl) Create_RegistrationToken(ctx context.Context,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (obj *postgresImpl) Create_ResetPasswordToken(ctx context.Context,
|
||||||
|
reset_password_token_secret ResetPasswordToken_Secret_Field,
|
||||||
|
reset_password_token_owner_id ResetPasswordToken_OwnerId_Field) (
|
||||||
|
reset_password_token *ResetPasswordToken, err error) {
|
||||||
|
|
||||||
|
__now := obj.db.Hooks.Now().UTC()
|
||||||
|
__secret_val := reset_password_token_secret.value()
|
||||||
|
__owner_id_val := reset_password_token_owner_id.value()
|
||||||
|
__created_at_val := __now
|
||||||
|
|
||||||
|
var __embed_stmt = __sqlbundle_Literal("INSERT INTO reset_password_tokens ( secret, owner_id, created_at ) VALUES ( ?, ?, ? ) RETURNING reset_password_tokens.secret, reset_password_tokens.owner_id, reset_password_tokens.created_at")
|
||||||
|
|
||||||
|
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||||
|
obj.logStmt(__stmt, __secret_val, __owner_id_val, __created_at_val)
|
||||||
|
|
||||||
|
reset_password_token = &ResetPasswordToken{}
|
||||||
|
err = obj.driver.QueryRow(__stmt, __secret_val, __owner_id_val, __created_at_val).Scan(&reset_password_token.Secret, &reset_password_token.OwnerId, &reset_password_token.CreatedAt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, obj.makeErr(err)
|
||||||
|
}
|
||||||
|
return reset_password_token, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (obj *postgresImpl) Get_Irreparabledb_By_Segmentpath(ctx context.Context,
|
func (obj *postgresImpl) Get_Irreparabledb_By_Segmentpath(ctx context.Context,
|
||||||
irreparabledb_segmentpath Irreparabledb_Segmentpath_Field) (
|
irreparabledb_segmentpath Irreparabledb_Segmentpath_Field) (
|
||||||
irreparabledb *Irreparabledb, err error) {
|
irreparabledb *Irreparabledb, err error) {
|
||||||
@ -5102,6 +5209,48 @@ func (obj *postgresImpl) Get_RegistrationToken_By_OwnerId(ctx context.Context,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (obj *postgresImpl) Get_ResetPasswordToken_By_Secret(ctx context.Context,
|
||||||
|
reset_password_token_secret ResetPasswordToken_Secret_Field) (
|
||||||
|
reset_password_token *ResetPasswordToken, err error) {
|
||||||
|
|
||||||
|
var __embed_stmt = __sqlbundle_Literal("SELECT reset_password_tokens.secret, reset_password_tokens.owner_id, reset_password_tokens.created_at FROM reset_password_tokens WHERE reset_password_tokens.secret = ?")
|
||||||
|
|
||||||
|
var __values []interface{}
|
||||||
|
__values = append(__values, reset_password_token_secret.value())
|
||||||
|
|
||||||
|
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||||
|
obj.logStmt(__stmt, __values...)
|
||||||
|
|
||||||
|
reset_password_token = &ResetPasswordToken{}
|
||||||
|
err = obj.driver.QueryRow(__stmt, __values...).Scan(&reset_password_token.Secret, &reset_password_token.OwnerId, &reset_password_token.CreatedAt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, obj.makeErr(err)
|
||||||
|
}
|
||||||
|
return reset_password_token, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (obj *postgresImpl) Get_ResetPasswordToken_By_OwnerId(ctx context.Context,
|
||||||
|
reset_password_token_owner_id ResetPasswordToken_OwnerId_Field) (
|
||||||
|
reset_password_token *ResetPasswordToken, err error) {
|
||||||
|
|
||||||
|
var __embed_stmt = __sqlbundle_Literal("SELECT reset_password_tokens.secret, reset_password_tokens.owner_id, reset_password_tokens.created_at FROM reset_password_tokens WHERE reset_password_tokens.owner_id = ?")
|
||||||
|
|
||||||
|
var __values []interface{}
|
||||||
|
__values = append(__values, reset_password_token_owner_id.value())
|
||||||
|
|
||||||
|
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||||
|
obj.logStmt(__stmt, __values...)
|
||||||
|
|
||||||
|
reset_password_token = &ResetPasswordToken{}
|
||||||
|
err = obj.driver.QueryRow(__stmt, __values...).Scan(&reset_password_token.Secret, &reset_password_token.OwnerId, &reset_password_token.CreatedAt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, obj.makeErr(err)
|
||||||
|
}
|
||||||
|
return reset_password_token, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (obj *postgresImpl) Update_Irreparabledb_By_Segmentpath(ctx context.Context,
|
func (obj *postgresImpl) Update_Irreparabledb_By_Segmentpath(ctx context.Context,
|
||||||
irreparabledb_segmentpath Irreparabledb_Segmentpath_Field,
|
irreparabledb_segmentpath Irreparabledb_Segmentpath_Field,
|
||||||
update Irreparabledb_Update_Fields) (
|
update Irreparabledb_Update_Fields) (
|
||||||
@ -5846,6 +5995,32 @@ func (obj *postgresImpl) Delete_CertRecord_By_Id(ctx context.Context,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (obj *postgresImpl) Delete_ResetPasswordToken_By_Secret(ctx context.Context,
|
||||||
|
reset_password_token_secret ResetPasswordToken_Secret_Field) (
|
||||||
|
deleted bool, err error) {
|
||||||
|
|
||||||
|
var __embed_stmt = __sqlbundle_Literal("DELETE FROM reset_password_tokens WHERE reset_password_tokens.secret = ?")
|
||||||
|
|
||||||
|
var __values []interface{}
|
||||||
|
__values = append(__values, reset_password_token_secret.value())
|
||||||
|
|
||||||
|
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||||
|
obj.logStmt(__stmt, __values...)
|
||||||
|
|
||||||
|
__res, err := obj.driver.Exec(__stmt, __values...)
|
||||||
|
if err != nil {
|
||||||
|
return false, obj.makeErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
__count, err := __res.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return false, obj.makeErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return __count > 0, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (impl postgresImpl) isConstraintError(err error) (
|
func (impl postgresImpl) isConstraintError(err error) (
|
||||||
constraint string, ok bool) {
|
constraint string, ok bool) {
|
||||||
if e, ok := err.(*pq.Error); ok {
|
if e, ok := err.(*pq.Error); ok {
|
||||||
@ -5924,6 +6099,16 @@ func (obj *postgresImpl) deleteAll(ctx context.Context) (count int64, err error)
|
|||||||
return 0, obj.makeErr(err)
|
return 0, obj.makeErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__count, err = __res.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return 0, obj.makeErr(err)
|
||||||
|
}
|
||||||
|
count += __count
|
||||||
|
__res, err = obj.driver.Exec("DELETE FROM reset_password_tokens;")
|
||||||
|
if err != nil {
|
||||||
|
return 0, obj.makeErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
__count, err = __res.RowsAffected()
|
__count, err = __res.RowsAffected()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, obj.makeErr(err)
|
return 0, obj.makeErr(err)
|
||||||
@ -6549,6 +6734,33 @@ func (obj *sqlite3Impl) Create_RegistrationToken(ctx context.Context,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (obj *sqlite3Impl) Create_ResetPasswordToken(ctx context.Context,
|
||||||
|
reset_password_token_secret ResetPasswordToken_Secret_Field,
|
||||||
|
reset_password_token_owner_id ResetPasswordToken_OwnerId_Field) (
|
||||||
|
reset_password_token *ResetPasswordToken, err error) {
|
||||||
|
|
||||||
|
__now := obj.db.Hooks.Now().UTC()
|
||||||
|
__secret_val := reset_password_token_secret.value()
|
||||||
|
__owner_id_val := reset_password_token_owner_id.value()
|
||||||
|
__created_at_val := __now
|
||||||
|
|
||||||
|
var __embed_stmt = __sqlbundle_Literal("INSERT INTO reset_password_tokens ( secret, owner_id, created_at ) VALUES ( ?, ?, ? )")
|
||||||
|
|
||||||
|
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||||
|
obj.logStmt(__stmt, __secret_val, __owner_id_val, __created_at_val)
|
||||||
|
|
||||||
|
__res, err := obj.driver.Exec(__stmt, __secret_val, __owner_id_val, __created_at_val)
|
||||||
|
if err != nil {
|
||||||
|
return nil, obj.makeErr(err)
|
||||||
|
}
|
||||||
|
__pk, err := __res.LastInsertId()
|
||||||
|
if err != nil {
|
||||||
|
return nil, obj.makeErr(err)
|
||||||
|
}
|
||||||
|
return obj.getLastResetPasswordToken(ctx, __pk)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (obj *sqlite3Impl) Get_Irreparabledb_By_Segmentpath(ctx context.Context,
|
func (obj *sqlite3Impl) Get_Irreparabledb_By_Segmentpath(ctx context.Context,
|
||||||
irreparabledb_segmentpath Irreparabledb_Segmentpath_Field) (
|
irreparabledb_segmentpath Irreparabledb_Segmentpath_Field) (
|
||||||
irreparabledb *Irreparabledb, err error) {
|
irreparabledb *Irreparabledb, err error) {
|
||||||
@ -7519,6 +7731,48 @@ func (obj *sqlite3Impl) Get_RegistrationToken_By_OwnerId(ctx context.Context,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (obj *sqlite3Impl) Get_ResetPasswordToken_By_Secret(ctx context.Context,
|
||||||
|
reset_password_token_secret ResetPasswordToken_Secret_Field) (
|
||||||
|
reset_password_token *ResetPasswordToken, err error) {
|
||||||
|
|
||||||
|
var __embed_stmt = __sqlbundle_Literal("SELECT reset_password_tokens.secret, reset_password_tokens.owner_id, reset_password_tokens.created_at FROM reset_password_tokens WHERE reset_password_tokens.secret = ?")
|
||||||
|
|
||||||
|
var __values []interface{}
|
||||||
|
__values = append(__values, reset_password_token_secret.value())
|
||||||
|
|
||||||
|
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||||
|
obj.logStmt(__stmt, __values...)
|
||||||
|
|
||||||
|
reset_password_token = &ResetPasswordToken{}
|
||||||
|
err = obj.driver.QueryRow(__stmt, __values...).Scan(&reset_password_token.Secret, &reset_password_token.OwnerId, &reset_password_token.CreatedAt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, obj.makeErr(err)
|
||||||
|
}
|
||||||
|
return reset_password_token, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (obj *sqlite3Impl) Get_ResetPasswordToken_By_OwnerId(ctx context.Context,
|
||||||
|
reset_password_token_owner_id ResetPasswordToken_OwnerId_Field) (
|
||||||
|
reset_password_token *ResetPasswordToken, err error) {
|
||||||
|
|
||||||
|
var __embed_stmt = __sqlbundle_Literal("SELECT reset_password_tokens.secret, reset_password_tokens.owner_id, reset_password_tokens.created_at FROM reset_password_tokens WHERE reset_password_tokens.owner_id = ?")
|
||||||
|
|
||||||
|
var __values []interface{}
|
||||||
|
__values = append(__values, reset_password_token_owner_id.value())
|
||||||
|
|
||||||
|
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||||
|
obj.logStmt(__stmt, __values...)
|
||||||
|
|
||||||
|
reset_password_token = &ResetPasswordToken{}
|
||||||
|
err = obj.driver.QueryRow(__stmt, __values...).Scan(&reset_password_token.Secret, &reset_password_token.OwnerId, &reset_password_token.CreatedAt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, obj.makeErr(err)
|
||||||
|
}
|
||||||
|
return reset_password_token, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (obj *sqlite3Impl) Update_Irreparabledb_By_Segmentpath(ctx context.Context,
|
func (obj *sqlite3Impl) Update_Irreparabledb_By_Segmentpath(ctx context.Context,
|
||||||
irreparabledb_segmentpath Irreparabledb_Segmentpath_Field,
|
irreparabledb_segmentpath Irreparabledb_Segmentpath_Field,
|
||||||
update Irreparabledb_Update_Fields) (
|
update Irreparabledb_Update_Fields) (
|
||||||
@ -8343,6 +8597,32 @@ func (obj *sqlite3Impl) Delete_CertRecord_By_Id(ctx context.Context,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (obj *sqlite3Impl) Delete_ResetPasswordToken_By_Secret(ctx context.Context,
|
||||||
|
reset_password_token_secret ResetPasswordToken_Secret_Field) (
|
||||||
|
deleted bool, err error) {
|
||||||
|
|
||||||
|
var __embed_stmt = __sqlbundle_Literal("DELETE FROM reset_password_tokens WHERE reset_password_tokens.secret = ?")
|
||||||
|
|
||||||
|
var __values []interface{}
|
||||||
|
__values = append(__values, reset_password_token_secret.value())
|
||||||
|
|
||||||
|
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||||
|
obj.logStmt(__stmt, __values...)
|
||||||
|
|
||||||
|
__res, err := obj.driver.Exec(__stmt, __values...)
|
||||||
|
if err != nil {
|
||||||
|
return false, obj.makeErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
__count, err := __res.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return false, obj.makeErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return __count > 0, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (obj *sqlite3Impl) getLastIrreparabledb(ctx context.Context,
|
func (obj *sqlite3Impl) getLastIrreparabledb(ctx context.Context,
|
||||||
pk int64) (
|
pk int64) (
|
||||||
irreparabledb *Irreparabledb, err error) {
|
irreparabledb *Irreparabledb, err error) {
|
||||||
@ -8613,6 +8893,24 @@ func (obj *sqlite3Impl) getLastRegistrationToken(ctx context.Context,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (obj *sqlite3Impl) getLastResetPasswordToken(ctx context.Context,
|
||||||
|
pk int64) (
|
||||||
|
reset_password_token *ResetPasswordToken, err error) {
|
||||||
|
|
||||||
|
var __embed_stmt = __sqlbundle_Literal("SELECT reset_password_tokens.secret, reset_password_tokens.owner_id, reset_password_tokens.created_at FROM reset_password_tokens WHERE _rowid_ = ?")
|
||||||
|
|
||||||
|
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||||
|
obj.logStmt(__stmt, pk)
|
||||||
|
|
||||||
|
reset_password_token = &ResetPasswordToken{}
|
||||||
|
err = obj.driver.QueryRow(__stmt, pk).Scan(&reset_password_token.Secret, &reset_password_token.OwnerId, &reset_password_token.CreatedAt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, obj.makeErr(err)
|
||||||
|
}
|
||||||
|
return reset_password_token, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (impl sqlite3Impl) isConstraintError(err error) (
|
func (impl sqlite3Impl) isConstraintError(err error) (
|
||||||
constraint string, ok bool) {
|
constraint string, ok bool) {
|
||||||
if e, ok := err.(sqlite3.Error); ok {
|
if e, ok := err.(sqlite3.Error); ok {
|
||||||
@ -8696,6 +8994,16 @@ func (obj *sqlite3Impl) deleteAll(ctx context.Context) (count int64, err error)
|
|||||||
return 0, obj.makeErr(err)
|
return 0, obj.makeErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__count, err = __res.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return 0, obj.makeErr(err)
|
||||||
|
}
|
||||||
|
count += __count
|
||||||
|
__res, err = obj.driver.Exec("DELETE FROM reset_password_tokens;")
|
||||||
|
if err != nil {
|
||||||
|
return 0, obj.makeErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
__count, err = __res.RowsAffected()
|
__count, err = __res.RowsAffected()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, obj.makeErr(err)
|
return 0, obj.makeErr(err)
|
||||||
@ -9151,6 +9459,18 @@ func (rx *Rx) Create_RegistrationToken(ctx context.Context,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rx *Rx) Create_ResetPasswordToken(ctx context.Context,
|
||||||
|
reset_password_token_secret ResetPasswordToken_Secret_Field,
|
||||||
|
reset_password_token_owner_id ResetPasswordToken_OwnerId_Field) (
|
||||||
|
reset_password_token *ResetPasswordToken, err error) {
|
||||||
|
var tx *Tx
|
||||||
|
if tx, err = rx.getTx(ctx); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return tx.Create_ResetPasswordToken(ctx, reset_password_token_secret, reset_password_token_owner_id)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (rx *Rx) Create_SerialNumber(ctx context.Context,
|
func (rx *Rx) Create_SerialNumber(ctx context.Context,
|
||||||
serial_number_serial_number SerialNumber_SerialNumber_Field,
|
serial_number_serial_number SerialNumber_SerialNumber_Field,
|
||||||
serial_number_bucket_id SerialNumber_BucketId_Field,
|
serial_number_bucket_id SerialNumber_BucketId_Field,
|
||||||
@ -9285,6 +9605,16 @@ func (rx *Rx) Delete_Project_By_Id(ctx context.Context,
|
|||||||
return tx.Delete_Project_By_Id(ctx, project_id)
|
return tx.Delete_Project_By_Id(ctx, project_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rx *Rx) Delete_ResetPasswordToken_By_Secret(ctx context.Context,
|
||||||
|
reset_password_token_secret ResetPasswordToken_Secret_Field) (
|
||||||
|
deleted bool, err error) {
|
||||||
|
var tx *Tx
|
||||||
|
if tx, err = rx.getTx(ctx); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return tx.Delete_ResetPasswordToken_By_Secret(ctx, reset_password_token_secret)
|
||||||
|
}
|
||||||
|
|
||||||
func (rx *Rx) Delete_SerialNumber_By_ExpiresAt_LessOrEqual(ctx context.Context,
|
func (rx *Rx) Delete_SerialNumber_By_ExpiresAt_LessOrEqual(ctx context.Context,
|
||||||
serial_number_expires_at_less_or_equal SerialNumber_ExpiresAt_Field) (
|
serial_number_expires_at_less_or_equal SerialNumber_ExpiresAt_Field) (
|
||||||
count int64, err error) {
|
count int64, err error) {
|
||||||
@ -9471,6 +9801,26 @@ func (rx *Rx) Get_RegistrationToken_By_Secret(ctx context.Context,
|
|||||||
return tx.Get_RegistrationToken_By_Secret(ctx, registration_token_secret)
|
return tx.Get_RegistrationToken_By_Secret(ctx, registration_token_secret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rx *Rx) Get_ResetPasswordToken_By_OwnerId(ctx context.Context,
|
||||||
|
reset_password_token_owner_id ResetPasswordToken_OwnerId_Field) (
|
||||||
|
reset_password_token *ResetPasswordToken, err error) {
|
||||||
|
var tx *Tx
|
||||||
|
if tx, err = rx.getTx(ctx); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return tx.Get_ResetPasswordToken_By_OwnerId(ctx, reset_password_token_owner_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rx *Rx) Get_ResetPasswordToken_By_Secret(ctx context.Context,
|
||||||
|
reset_password_token_secret ResetPasswordToken_Secret_Field) (
|
||||||
|
reset_password_token *ResetPasswordToken, err error) {
|
||||||
|
var tx *Tx
|
||||||
|
if tx, err = rx.getTx(ctx); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return tx.Get_ResetPasswordToken_By_Secret(ctx, reset_password_token_secret)
|
||||||
|
}
|
||||||
|
|
||||||
func (rx *Rx) Get_StoragenodeStorageTally_By_Id(ctx context.Context,
|
func (rx *Rx) Get_StoragenodeStorageTally_By_Id(ctx context.Context,
|
||||||
storagenode_storage_tally_id StoragenodeStorageTally_Id_Field) (
|
storagenode_storage_tally_id StoragenodeStorageTally_Id_Field) (
|
||||||
storagenode_storage_tally *StoragenodeStorageTally, err error) {
|
storagenode_storage_tally *StoragenodeStorageTally, err error) {
|
||||||
@ -9794,6 +10144,11 @@ type Methods interface {
|
|||||||
optional RegistrationToken_Create_Fields) (
|
optional RegistrationToken_Create_Fields) (
|
||||||
registration_token *RegistrationToken, err error)
|
registration_token *RegistrationToken, err error)
|
||||||
|
|
||||||
|
Create_ResetPasswordToken(ctx context.Context,
|
||||||
|
reset_password_token_secret ResetPasswordToken_Secret_Field,
|
||||||
|
reset_password_token_owner_id ResetPasswordToken_OwnerId_Field) (
|
||||||
|
reset_password_token *ResetPasswordToken, err error)
|
||||||
|
|
||||||
Create_SerialNumber(ctx context.Context,
|
Create_SerialNumber(ctx context.Context,
|
||||||
serial_number_serial_number SerialNumber_SerialNumber_Field,
|
serial_number_serial_number SerialNumber_SerialNumber_Field,
|
||||||
serial_number_bucket_id SerialNumber_BucketId_Field,
|
serial_number_bucket_id SerialNumber_BucketId_Field,
|
||||||
@ -9852,6 +10207,10 @@ type Methods interface {
|
|||||||
project_id Project_Id_Field) (
|
project_id Project_Id_Field) (
|
||||||
deleted bool, err error)
|
deleted bool, err error)
|
||||||
|
|
||||||
|
Delete_ResetPasswordToken_By_Secret(ctx context.Context,
|
||||||
|
reset_password_token_secret ResetPasswordToken_Secret_Field) (
|
||||||
|
deleted bool, err error)
|
||||||
|
|
||||||
Delete_SerialNumber_By_ExpiresAt_LessOrEqual(ctx context.Context,
|
Delete_SerialNumber_By_ExpiresAt_LessOrEqual(ctx context.Context,
|
||||||
serial_number_expires_at_less_or_equal SerialNumber_ExpiresAt_Field) (
|
serial_number_expires_at_less_or_equal SerialNumber_ExpiresAt_Field) (
|
||||||
count int64, err error)
|
count int64, err error)
|
||||||
@ -9929,6 +10288,14 @@ type Methods interface {
|
|||||||
registration_token_secret RegistrationToken_Secret_Field) (
|
registration_token_secret RegistrationToken_Secret_Field) (
|
||||||
registration_token *RegistrationToken, err error)
|
registration_token *RegistrationToken, err error)
|
||||||
|
|
||||||
|
Get_ResetPasswordToken_By_OwnerId(ctx context.Context,
|
||||||
|
reset_password_token_owner_id ResetPasswordToken_OwnerId_Field) (
|
||||||
|
reset_password_token *ResetPasswordToken, err error)
|
||||||
|
|
||||||
|
Get_ResetPasswordToken_By_Secret(ctx context.Context,
|
||||||
|
reset_password_token_secret ResetPasswordToken_Secret_Field) (
|
||||||
|
reset_password_token *ResetPasswordToken, err error)
|
||||||
|
|
||||||
Get_StoragenodeStorageTally_By_Id(ctx context.Context,
|
Get_StoragenodeStorageTally_By_Id(ctx context.Context,
|
||||||
storagenode_storage_tally_id StoragenodeStorageTally_Id_Field) (
|
storagenode_storage_tally_id StoragenodeStorageTally_Id_Field) (
|
||||||
storagenode_storage_tally *StoragenodeStorageTally, err error)
|
storagenode_storage_tally *StoragenodeStorageTally, err error)
|
||||||
|
@ -128,6 +128,13 @@ CREATE TABLE registration_tokens (
|
|||||||
PRIMARY KEY ( secret ),
|
PRIMARY KEY ( secret ),
|
||||||
UNIQUE ( owner_id )
|
UNIQUE ( owner_id )
|
||||||
);
|
);
|
||||||
|
CREATE TABLE reset_password_tokens (
|
||||||
|
secret bytea NOT NULL,
|
||||||
|
owner_id bytea NOT NULL,
|
||||||
|
created_at timestamp with time zone NOT NULL,
|
||||||
|
PRIMARY KEY ( secret ),
|
||||||
|
UNIQUE ( owner_id )
|
||||||
|
);
|
||||||
CREATE TABLE serial_numbers (
|
CREATE TABLE serial_numbers (
|
||||||
id serial NOT NULL,
|
id serial NOT NULL,
|
||||||
serial_number bytea NOT NULL,
|
serial_number bytea NOT NULL,
|
||||||
|
@ -128,6 +128,13 @@ CREATE TABLE registration_tokens (
|
|||||||
PRIMARY KEY ( secret ),
|
PRIMARY KEY ( secret ),
|
||||||
UNIQUE ( owner_id )
|
UNIQUE ( owner_id )
|
||||||
);
|
);
|
||||||
|
CREATE TABLE reset_password_tokens (
|
||||||
|
secret BLOB NOT NULL,
|
||||||
|
owner_id BLOB NOT NULL,
|
||||||
|
created_at TIMESTAMP NOT NULL,
|
||||||
|
PRIMARY KEY ( secret ),
|
||||||
|
UNIQUE ( owner_id )
|
||||||
|
);
|
||||||
CREATE TABLE serial_numbers (
|
CREATE TABLE serial_numbers (
|
||||||
id INTEGER NOT NULL,
|
id INTEGER NOT NULL,
|
||||||
serial_number BLOB NOT NULL,
|
serial_number BLOB NOT NULL,
|
||||||
|
@ -361,6 +361,47 @@ func (m *lockedRegistrationTokens) UpdateOwner(ctx context.Context, secret conso
|
|||||||
return m.db.UpdateOwner(ctx, secret, ownerID)
|
return m.db.UpdateOwner(ctx, secret, ownerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResetPasswordTokens is a getter for ResetPasswordTokens repository
|
||||||
|
func (m *lockedConsole) ResetPasswordTokens() console.ResetPasswordTokens {
|
||||||
|
m.Lock()
|
||||||
|
defer m.Unlock()
|
||||||
|
return &lockedResetPasswordTokens{m.Locker, m.db.ResetPasswordTokens()}
|
||||||
|
}
|
||||||
|
|
||||||
|
// lockedResetPasswordTokens implements locking wrapper for console.ResetPasswordTokens
|
||||||
|
type lockedResetPasswordTokens struct {
|
||||||
|
sync.Locker
|
||||||
|
db console.ResetPasswordTokens
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create creates new reset password token
|
||||||
|
func (m *lockedResetPasswordTokens) Create(ctx context.Context, ownerID uuid.UUID) (*console.ResetPasswordToken, error) {
|
||||||
|
m.Lock()
|
||||||
|
defer m.Unlock()
|
||||||
|
return m.db.Create(ctx, ownerID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete deletes ResetPasswordToken by ResetPasswordSecret
|
||||||
|
func (m *lockedResetPasswordTokens) Delete(ctx context.Context, secret console.ResetPasswordSecret) error {
|
||||||
|
m.Lock()
|
||||||
|
defer m.Unlock()
|
||||||
|
return m.db.Delete(ctx, secret)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetByOwnerID retrieves ResetPasswordToken by ownerID
|
||||||
|
func (m *lockedResetPasswordTokens) GetByOwnerID(ctx context.Context, ownerID uuid.UUID) (*console.ResetPasswordToken, error) {
|
||||||
|
m.Lock()
|
||||||
|
defer m.Unlock()
|
||||||
|
return m.db.GetByOwnerID(ctx, ownerID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBySecret retrieves ResetPasswordToken with given secret
|
||||||
|
func (m *lockedResetPasswordTokens) GetBySecret(ctx context.Context, secret console.ResetPasswordSecret) (*console.ResetPasswordToken, error) {
|
||||||
|
m.Lock()
|
||||||
|
defer m.Unlock()
|
||||||
|
return m.db.GetBySecret(ctx, secret)
|
||||||
|
}
|
||||||
|
|
||||||
// UsageRollups is a getter for UsageRollups repository
|
// UsageRollups is a getter for UsageRollups repository
|
||||||
func (m *lockedConsole) UsageRollups() console.UsageRollups {
|
func (m *lockedConsole) UsageRollups() console.UsageRollups {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
|
@ -620,6 +620,19 @@ func (db *DB) PostgresMigration() *migrate.Migration {
|
|||||||
`ALTER TABLE storagenode_storage_tallies DROP COLUMN created_at`,
|
`ALTER TABLE storagenode_storage_tallies DROP COLUMN created_at`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Description: "Added new table to store reset password tokens",
|
||||||
|
Version: 19,
|
||||||
|
Action: migrate.SQL{`
|
||||||
|
CREATE TABLE reset_password_tokens (
|
||||||
|
secret bytea NOT NULL,
|
||||||
|
owner_id bytea NOT NULL,
|
||||||
|
created_at timestamp with time zone NOT NULL,
|
||||||
|
PRIMARY KEY ( secret ),
|
||||||
|
UNIQUE ( owner_id )
|
||||||
|
);`,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
101
satellite/satellitedb/resetpasstokens.go
Normal file
101
satellite/satellitedb/resetpasstokens.go
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
// Copyright (C) 2018 Storj Labs, Inc.
|
||||||
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
|
package satellitedb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/skyrings/skyring-common/tools/uuid"
|
||||||
|
|
||||||
|
"storj.io/storj/satellite/console"
|
||||||
|
dbx "storj.io/storj/satellite/satellitedb/dbx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type resetPasswordTokens struct {
|
||||||
|
db dbx.Methods
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create creates new reset password token
|
||||||
|
func (rpt *resetPasswordTokens) Create(ctx context.Context, ownerID uuid.UUID) (*console.ResetPasswordToken, error) {
|
||||||
|
secret, err := console.NewResetPasswordSecret()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resToken, err := rpt.db.Create_ResetPasswordToken(
|
||||||
|
ctx,
|
||||||
|
dbx.ResetPasswordToken_Secret(secret[:]),
|
||||||
|
dbx.ResetPasswordToken_OwnerId(ownerID[:]),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resetPasswordTokenFromDBX(resToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBySecret retrieves ResetPasswordToken with given Secret
|
||||||
|
func (rpt *resetPasswordTokens) GetBySecret(ctx context.Context, secret console.ResetPasswordSecret) (*console.ResetPasswordToken, error) {
|
||||||
|
resToken, err := rpt.db.Get_ResetPasswordToken_By_Secret(
|
||||||
|
ctx,
|
||||||
|
dbx.ResetPasswordToken_Secret(secret[:]),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resetPasswordTokenFromDBX(resToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetByOwnerID retrieves ResetPasswordToken by ownerID
|
||||||
|
func (rpt *resetPasswordTokens) GetByOwnerID(ctx context.Context, ownerID uuid.UUID) (*console.ResetPasswordToken, error) {
|
||||||
|
resToken, err := rpt.db.Get_ResetPasswordToken_By_OwnerId(
|
||||||
|
ctx,
|
||||||
|
dbx.ResetPasswordToken_OwnerId(ownerID[:]),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resetPasswordTokenFromDBX(resToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete deletes ResetPasswordToken by ResetPasswordSecret
|
||||||
|
func (rpt *resetPasswordTokens) Delete(ctx context.Context, secret console.ResetPasswordSecret) error {
|
||||||
|
_, err := rpt.db.Delete_ResetPasswordToken_By_Secret(
|
||||||
|
ctx,
|
||||||
|
dbx.ResetPasswordToken_Secret(secret[:]),
|
||||||
|
)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// resetPasswordTokenFromDBX is used for creating ResetPasswordToken entity from autogenerated dbx.ResetPasswordToken struct
|
||||||
|
func resetPasswordTokenFromDBX(resetToken *dbx.ResetPasswordToken) (*console.ResetPasswordToken, error) {
|
||||||
|
if resetToken == nil {
|
||||||
|
return nil, errors.New("token parameter is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
var secret [32]byte
|
||||||
|
|
||||||
|
copy(secret[:], resetToken.Secret)
|
||||||
|
|
||||||
|
result := &console.ResetPasswordToken{
|
||||||
|
Secret: secret,
|
||||||
|
OwnerID: nil,
|
||||||
|
CreatedAt: resetToken.CreatedAt,
|
||||||
|
}
|
||||||
|
|
||||||
|
if resetToken.OwnerId != nil {
|
||||||
|
ownerID, err := bytesToUUID(resetToken.OwnerId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result.OwnerID = &ownerID
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
242
satellite/satellitedb/testdata/postgres.v19.sql
vendored
Normal file
242
satellite/satellitedb/testdata/postgres.v19.sql
vendored
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
-- Copied from the corresponding version of dbx generated schema
|
||||||
|
CREATE TABLE accounting_rollups (
|
||||||
|
id bigserial NOT NULL,
|
||||||
|
node_id bytea NOT NULL,
|
||||||
|
start_time timestamp with time zone NOT NULL,
|
||||||
|
put_total bigint NOT NULL,
|
||||||
|
get_total bigint NOT NULL,
|
||||||
|
get_audit_total bigint NOT NULL,
|
||||||
|
get_repair_total bigint NOT NULL,
|
||||||
|
put_repair_total bigint NOT NULL,
|
||||||
|
at_rest_total double precision NOT NULL,
|
||||||
|
PRIMARY KEY ( id )
|
||||||
|
);
|
||||||
|
CREATE TABLE accounting_timestamps (
|
||||||
|
name text NOT NULL,
|
||||||
|
value timestamp with time zone NOT NULL,
|
||||||
|
PRIMARY KEY ( name )
|
||||||
|
);
|
||||||
|
CREATE TABLE bucket_bandwidth_rollups (
|
||||||
|
bucket_name bytea NOT NULL,
|
||||||
|
project_id bytea NOT NULL,
|
||||||
|
interval_start timestamp NOT NULL,
|
||||||
|
interval_seconds integer NOT NULL,
|
||||||
|
action integer NOT NULL,
|
||||||
|
inline bigint NOT NULL,
|
||||||
|
allocated bigint NOT NULL,
|
||||||
|
settled bigint NOT NULL,
|
||||||
|
PRIMARY KEY ( bucket_name, project_id, interval_start, action )
|
||||||
|
);
|
||||||
|
CREATE TABLE bucket_storage_tallies (
|
||||||
|
bucket_name bytea NOT NULL,
|
||||||
|
project_id bytea NOT NULL,
|
||||||
|
interval_start timestamp NOT NULL,
|
||||||
|
inline bigint NOT NULL,
|
||||||
|
remote bigint NOT NULL,
|
||||||
|
remote_segments_count integer NOT NULL,
|
||||||
|
inline_segments_count integer NOT NULL,
|
||||||
|
object_count integer NOT NULL,
|
||||||
|
metadata_size bigint NOT NULL,
|
||||||
|
PRIMARY KEY ( bucket_name, project_id, interval_start )
|
||||||
|
);
|
||||||
|
CREATE TABLE bucket_usages (
|
||||||
|
id bytea NOT NULL,
|
||||||
|
bucket_id bytea NOT NULL,
|
||||||
|
rollup_end_time timestamp with time zone NOT NULL,
|
||||||
|
remote_stored_data bigint NOT NULL,
|
||||||
|
inline_stored_data bigint NOT NULL,
|
||||||
|
remote_segments integer NOT NULL,
|
||||||
|
inline_segments integer NOT NULL,
|
||||||
|
objects integer NOT NULL,
|
||||||
|
metadata_size bigint NOT NULL,
|
||||||
|
repair_egress bigint NOT NULL,
|
||||||
|
get_egress bigint NOT NULL,
|
||||||
|
audit_egress bigint NOT NULL,
|
||||||
|
PRIMARY KEY ( id )
|
||||||
|
);
|
||||||
|
CREATE TABLE bwagreements (
|
||||||
|
serialnum text NOT NULL,
|
||||||
|
storage_node_id bytea NOT NULL,
|
||||||
|
uplink_id bytea NOT NULL,
|
||||||
|
action bigint NOT NULL,
|
||||||
|
total bigint NOT NULL,
|
||||||
|
created_at timestamp with time zone NOT NULL,
|
||||||
|
expires_at timestamp with time zone NOT NULL,
|
||||||
|
PRIMARY KEY ( serialnum )
|
||||||
|
);
|
||||||
|
CREATE TABLE certRecords (
|
||||||
|
publickey bytea NOT NULL,
|
||||||
|
id bytea NOT NULL,
|
||||||
|
update_at timestamp with time zone NOT NULL,
|
||||||
|
PRIMARY KEY ( id )
|
||||||
|
);
|
||||||
|
CREATE TABLE injuredsegments (
|
||||||
|
path text NOT NULL,
|
||||||
|
data bytea NOT NULL,
|
||||||
|
attempted timestamp,
|
||||||
|
PRIMARY KEY ( path )
|
||||||
|
);
|
||||||
|
CREATE TABLE irreparabledbs (
|
||||||
|
segmentpath bytea NOT NULL,
|
||||||
|
segmentdetail bytea NOT NULL,
|
||||||
|
pieces_lost_count bigint NOT NULL,
|
||||||
|
seg_damaged_unix_sec bigint NOT NULL,
|
||||||
|
repair_attempt_count bigint NOT NULL,
|
||||||
|
PRIMARY KEY ( segmentpath )
|
||||||
|
);
|
||||||
|
CREATE TABLE nodes (
|
||||||
|
id bytea NOT NULL,
|
||||||
|
address text NOT NULL,
|
||||||
|
protocol integer NOT NULL,
|
||||||
|
type integer NOT NULL,
|
||||||
|
email text NOT NULL,
|
||||||
|
wallet text NOT NULL,
|
||||||
|
free_bandwidth bigint NOT NULL,
|
||||||
|
free_disk bigint NOT NULL,
|
||||||
|
major bigint NOT NULL,
|
||||||
|
minor bigint NOT NULL,
|
||||||
|
patch bigint NOT NULL,
|
||||||
|
hash text NOT NULL,
|
||||||
|
timestamp timestamp with time zone NOT NULL,
|
||||||
|
release boolean NOT NULL,
|
||||||
|
latency_90 bigint NOT NULL,
|
||||||
|
audit_success_count bigint NOT NULL,
|
||||||
|
total_audit_count bigint NOT NULL,
|
||||||
|
audit_success_ratio double precision NOT NULL,
|
||||||
|
uptime_success_count bigint NOT NULL,
|
||||||
|
total_uptime_count bigint NOT NULL,
|
||||||
|
uptime_ratio double precision NOT NULL,
|
||||||
|
created_at timestamp with time zone NOT NULL,
|
||||||
|
updated_at timestamp with time zone NOT NULL,
|
||||||
|
last_contact_success timestamp with time zone NOT NULL,
|
||||||
|
last_contact_failure timestamp with time zone NOT NULL,
|
||||||
|
PRIMARY KEY ( id )
|
||||||
|
);
|
||||||
|
CREATE TABLE projects (
|
||||||
|
id bytea NOT NULL,
|
||||||
|
name text NOT NULL,
|
||||||
|
description text NOT NULL,
|
||||||
|
created_at timestamp with time zone NOT NULL,
|
||||||
|
PRIMARY KEY ( id )
|
||||||
|
);
|
||||||
|
CREATE TABLE registration_tokens (
|
||||||
|
secret bytea NOT NULL,
|
||||||
|
owner_id bytea,
|
||||||
|
project_limit integer NOT NULL,
|
||||||
|
created_at timestamp with time zone NOT NULL,
|
||||||
|
PRIMARY KEY ( secret ),
|
||||||
|
UNIQUE ( owner_id )
|
||||||
|
);
|
||||||
|
CREATE TABLE serial_numbers (
|
||||||
|
id serial NOT NULL,
|
||||||
|
serial_number bytea NOT NULL,
|
||||||
|
bucket_id bytea NOT NULL,
|
||||||
|
expires_at timestamp NOT NULL,
|
||||||
|
PRIMARY KEY ( id )
|
||||||
|
);
|
||||||
|
CREATE TABLE storagenode_bandwidth_rollups (
|
||||||
|
storagenode_id bytea NOT NULL,
|
||||||
|
interval_start timestamp NOT NULL,
|
||||||
|
interval_seconds integer NOT NULL,
|
||||||
|
action integer NOT NULL,
|
||||||
|
allocated bigint NOT NULL,
|
||||||
|
settled bigint NOT NULL,
|
||||||
|
PRIMARY KEY ( storagenode_id, interval_start, action )
|
||||||
|
);
|
||||||
|
CREATE TABLE storagenode_storage_tallies (
|
||||||
|
id bigserial NOT NULL,
|
||||||
|
node_id bytea NOT NULL,
|
||||||
|
interval_end_time timestamp with time zone NOT NULL,
|
||||||
|
data_total double precision NOT NULL,
|
||||||
|
PRIMARY KEY ( id )
|
||||||
|
);
|
||||||
|
CREATE TABLE users (
|
||||||
|
id bytea NOT NULL,
|
||||||
|
full_name text NOT NULL,
|
||||||
|
short_name text,
|
||||||
|
email text NOT NULL,
|
||||||
|
password_hash bytea NOT NULL,
|
||||||
|
status integer NOT NULL,
|
||||||
|
created_at timestamp with time zone NOT NULL,
|
||||||
|
PRIMARY KEY ( id )
|
||||||
|
);
|
||||||
|
CREATE TABLE api_keys (
|
||||||
|
id bytea NOT NULL,
|
||||||
|
project_id bytea NOT NULL REFERENCES projects( id ) ON DELETE CASCADE,
|
||||||
|
key bytea NOT NULL,
|
||||||
|
name text NOT NULL,
|
||||||
|
created_at timestamp with time zone NOT NULL,
|
||||||
|
PRIMARY KEY ( id ),
|
||||||
|
UNIQUE ( key ),
|
||||||
|
UNIQUE ( name, project_id )
|
||||||
|
);
|
||||||
|
CREATE TABLE project_members (
|
||||||
|
member_id bytea NOT NULL REFERENCES users( id ) ON DELETE CASCADE,
|
||||||
|
project_id bytea NOT NULL REFERENCES projects( id ) ON DELETE CASCADE,
|
||||||
|
created_at timestamp with time zone NOT NULL,
|
||||||
|
PRIMARY KEY ( member_id, project_id )
|
||||||
|
);
|
||||||
|
CREATE TABLE used_serials (
|
||||||
|
serial_number_id integer NOT NULL REFERENCES serial_numbers( id ) ON DELETE CASCADE,
|
||||||
|
storage_node_id bytea NOT NULL,
|
||||||
|
PRIMARY KEY ( serial_number_id, storage_node_id )
|
||||||
|
);
|
||||||
|
CREATE TABLE reset_password_tokens (
|
||||||
|
secret bytea NOT NULL,
|
||||||
|
owner_id bytea NOT NULL,
|
||||||
|
created_at timestamp with time zone NOT NULL,
|
||||||
|
PRIMARY KEY ( secret ),
|
||||||
|
UNIQUE ( owner_id )
|
||||||
|
);
|
||||||
|
CREATE INDEX bucket_name_project_id_interval_start_interval_seconds ON bucket_bandwidth_rollups ( bucket_name, project_id, interval_start, interval_seconds );
|
||||||
|
CREATE UNIQUE INDEX bucket_id_rollup ON bucket_usages ( bucket_id, rollup_end_time );
|
||||||
|
CREATE UNIQUE INDEX serial_number ON serial_numbers ( serial_number );
|
||||||
|
CREATE INDEX serial_numbers_expires_at_index ON serial_numbers ( expires_at );
|
||||||
|
CREATE INDEX storagenode_id_interval_start_interval_seconds ON storagenode_bandwidth_rollups ( storagenode_id, interval_start, interval_seconds );
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
INSERT INTO "accounting_rollups"("id", "node_id", "start_time", "put_total", "get_total", "get_audit_total", "get_repair_total", "put_repair_total", "at_rest_total") VALUES (1, E'\\367M\\177\\251]t/\\022\\256\\214\\265\\025\\224\\204:\\217\\212\\0102<\\321\\374\\020&\\271Qc\\325\\261\\354\\246\\233'::bytea, '2019-02-09 00:00:00+00', 1000, 2000, 3000, 4000, 0, 5000);
|
||||||
|
|
||||||
|
INSERT INTO "accounting_timestamps" VALUES ('LastAtRestTally', '0001-01-01 00:00:00+00');
|
||||||
|
INSERT INTO "accounting_timestamps" VALUES ('LastRollup', '0001-01-01 00:00:00+00');
|
||||||
|
INSERT INTO "accounting_timestamps" VALUES ('LastBandwidthTally', '0001-01-01 00:00:00+00');
|
||||||
|
|
||||||
|
INSERT INTO "nodes"("id", "address", "protocol", "type", "email", "wallet", "free_bandwidth", "free_disk", "major", "minor", "patch", "hash", "timestamp", "release","latency_90", "audit_success_count", "total_audit_count", "audit_success_ratio", "uptime_success_count", "total_uptime_count", "uptime_ratio", "created_at", "updated_at", "last_contact_success", "last_contact_failure") VALUES (E'\\153\\313\\233\\074\\327\\177\\136\\070\\346\\001', '127.0.0.1:55516', 0, 4, '', '', -1, -1, 0, 1, 0, '', 'epoch', false, 0, 0, 5, 0, 0, 5, 0, '2019-02-14 08:07:31.028103+00', '2019-02-14 08:07:31.108963+00', 'epoch', 'epoch');
|
||||||
|
INSERT INTO "nodes"("id", "address", "protocol", "type", "email", "wallet", "free_bandwidth", "free_disk", "major", "minor", "patch", "hash", "timestamp", "release","latency_90", "audit_success_count", "total_audit_count", "audit_success_ratio", "uptime_success_count", "total_uptime_count", "uptime_ratio", "created_at", "updated_at", "last_contact_success", "last_contact_failure") VALUES (E'\\006\\223\\250R\\221\\005\\365\\377v>0\\266\\365\\216\\255?\\347\\244\\371?2\\264\\262\\230\\007<\\001\\262\\263\\237\\247n', '127.0.0.1:55518', 0, 4, '', '', -1, -1, 0, 1, 0, '', 'epoch', false, 0, 0, 0, 1, 3, 3, 1, '2019-02-14 08:07:31.028103+00', '2019-02-14 08:07:31.108963+00', 'epoch', 'epoch');
|
||||||
|
INSERT INTO "nodes"("id", "address", "protocol", "type", "email", "wallet", "free_bandwidth", "free_disk", "major", "minor", "patch", "hash", "timestamp", "release","latency_90", "audit_success_count", "total_audit_count", "audit_success_ratio", "uptime_success_count", "total_uptime_count", "uptime_ratio", "created_at", "updated_at", "last_contact_success", "last_contact_failure") VALUES (E'\\363\\342\\363\\371>+F\\256\\263\\300\\273|\\342N\\347\\014', '127.0.0.1:55517', 0, 4, '', '', -1, -1, 0, 1, 0, '', 'epoch', false, 0, 0, 0, 1, 0, 0, 1, '2019-02-14 08:07:31.028103+00', '2019-02-14 08:07:31.108963+00', 'epoch', 'epoch');
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO "projects"("id", "name", "description", "created_at") VALUES (E'\\022\\217/\\014\\376!K\\023\\276\\031\\311}m\\236\\205\\300'::bytea, 'ProjectName', 'projects description', '2019-02-14 08:28:24.254934+00');
|
||||||
|
INSERT INTO "api_keys"("id", "project_id", "key", "name", "created_at") VALUES (E'\\334/\\302;\\225\\355O\\323\\276f\\247\\354/6\\241\\033'::bytea, E'\\022\\217/\\014\\376!K\\023\\276\\031\\311}m\\236\\205\\300'::bytea, E'\\000]\\326N \\343\\270L\\327\\027\\337\\242\\240\\322mOl\\0318\\251.P I'::bytea, 'key 2', '2019-02-14 08:28:24.267934+00');
|
||||||
|
|
||||||
|
INSERT INTO "users"("id", "full_name", "short_name", "email", "password_hash", "status", "created_at") VALUES (E'\\363\\311\\033w\\222\\303Ci\\265\\343U\\303\\312\\204",'::bytea, 'Noahson', 'William', '1email1@ukr.net', E'some_readable_hash'::bytea, 1, '2019-02-14 08:28:24.614594+00');
|
||||||
|
INSERT INTO "projects"("id", "name", "description", "created_at") VALUES (E'\\363\\342\\363\\371>+F\\256\\263\\300\\273|\\342N\\347\\014'::bytea, 'projName1', 'Test project 1', '2019-02-14 08:28:24.636949+00');
|
||||||
|
INSERT INTO "project_members"("member_id", "project_id", "created_at") VALUES (E'\\363\\311\\033w\\222\\303Ci\\265\\343U\\303\\312\\204",'::bytea, E'\\363\\342\\363\\371>+F\\256\\263\\300\\273|\\342N\\347\\014'::bytea, '2019-02-14 08:28:24.677953+00');
|
||||||
|
|
||||||
|
INSERT INTO "bwagreements"("serialnum", "storage_node_id", "action", "total", "created_at", "expires_at", "uplink_id") VALUES ('8fc0ceaa-984c-4d52-bcf4-b5429e1e35e812FpiifDbcJkePa12jxjDEutKrfLmwzT7sz2jfVwpYqgtM8B74c', E'\\245Z[/\\333\\022\\011\\001\\036\\003\\204\\005\\032.\\206\\333E\\261\\342\\227=y,}aRaH6\\240\\370\\000'::bytea, 1, 666, '2019-02-14 15:09:54.420181+00', '2019-02-14 16:09:54+00', E'\\253Z+\\374eFm\\245$\\036\\206\\335\\247\\263\\350x\\\\\\304+\\364\\343\\364+\\276fIJQ\\361\\014\\232\\000'::bytea);
|
||||||
|
INSERT INTO "irreparabledbs" ("segmentpath", "segmentdetail", "pieces_lost_count", "seg_damaged_unix_sec", "repair_attempt_count") VALUES ('\x49616d5365676d656e746b6579696e666f30', '\x49616d5365676d656e7464657461696c696e666f30', 10, 1550159554, 10);
|
||||||
|
|
||||||
|
INSERT INTO "injuredsegments" ("path", "data") VALUES ('0', '\x0a0130120100');
|
||||||
|
INSERT INTO "injuredsegments" ("path", "data") VALUES ('here''s/a/great/path', '\x0a136865726527732f612f67726561742f70617468120a0102030405060708090a');
|
||||||
|
INSERT INTO "injuredsegments" ("path", "data") VALUES ('yet/another/cool/path', '\x0a157965742f616e6f746865722f636f6f6c2f70617468120a0102030405060708090a');
|
||||||
|
INSERT INTO "injuredsegments" ("path", "data") VALUES ('so/many/iconic/paths/to/choose/from', '\x0a23736f2f6d616e792f69636f6e69632f70617468732f746f2f63686f6f73652f66726f6d120a0102030405060708090a');
|
||||||
|
|
||||||
|
INSERT INTO "certrecords" VALUES (E'0Y0\\023\\006\\007*\\206H\\316=\\002\\001\\006\\010*\\206H\\316=\\003\\001\\007\\003B\\000\\004\\360\\267\\227\\377\\253u\\222\\337Y\\324C:GQ\\010\\277v\\010\\315D\\271\\333\\337.\\203\\023=C\\343\\014T%6\\027\\362?\\214\\326\\017U\\334\\000\\260\\224\\260J\\221\\304\\331F\\304\\221\\236zF,\\325\\326l\\215\\306\\365\\200\\022', E'L\\301|\\200\\247}F|1\\320\\232\\037n\\335\\241\\206\\244\\242\\207\\204.\\253\\357\\326\\352\\033Dt\\202`\\022\\325', '2019-02-14 08:07:31.335028+00');
|
||||||
|
|
||||||
|
INSERT INTO "bucket_usages" ("id", "bucket_id", "rollup_end_time", "remote_stored_data", "inline_stored_data", "remote_segments", "inline_segments", "objects", "metadata_size", "repair_egress", "get_egress", "audit_egress") VALUES (E'\\153\\313\\233\\074\\327\\177\\136\\070\\346\\001",'::bytea, E'\\366\\146\\032\\321\\316\\161\\070\\133\\302\\271",'::bytea, '2019-03-06 08:28:24.677953+00', 10, 11, 12, 13, 14, 15, 16, 17, 18);
|
||||||
|
|
||||||
|
INSERT INTO "registration_tokens" ("secret", "owner_id", "project_limit", "created_at") VALUES (E'\\070\\127\\144\\013\\332\\344\\102\\376\\306\\056\\303\\130\\106\\132\\321\\276\\321\\274\\170\\264\\054\\333\\221\\116\\154\\221\\335\\070\\220\\146\\344\\216'::bytea, null, 1, '2019-02-14 08:28:24.677953+00');
|
||||||
|
|
||||||
|
INSERT INTO "serial_numbers" ("id", "serial_number", "bucket_id", "expires_at") VALUES (1, E'0123456701234567'::bytea, E'\\363\\342\\363\\371>+F\\256\\263\\300\\273|\\342N\\347\\014/testbucket'::bytea, '2019-03-06 08:28:24.677953+00');
|
||||||
|
INSERT INTO "used_serials" ("serial_number_id", "storage_node_id") VALUES (1, E'\\006\\223\\250R\\221\\005\\365\\377v>0\\266\\365\\216\\255?\\347\\244\\371?2\\264\\262\\230\\007<\\001\\262\\263\\237\\247n');
|
||||||
|
|
||||||
|
INSERT INTO "storagenode_bandwidth_rollups" ("storagenode_id", "interval_start", "interval_seconds", "action", "allocated", "settled") VALUES (E'\\006\\223\\250R\\221\\005\\365\\377v>0\\266\\365\\216\\255?\\347\\244\\371?2\\264\\262\\230\\007<\\001\\262\\263\\237\\247n', '2019-03-06 08:00:00.000000+00', 3600, 1, 1024, 2024);
|
||||||
|
INSERT INTO "storagenode_storage_tallies" VALUES (1, E'\\3510\\323\\225"~\\036<\\342\\330m\\0253Jhr\\246\\233K\\246#\\2303\\351\\256\\275j\\212UM\\362\\207', '2019-02-14 08:16:57.812849+00', 1000);
|
||||||
|
|
||||||
|
INSERT INTO "bucket_bandwidth_rollups" ("bucket_name", "project_id", "interval_start", "interval_seconds", "action", "inline", "allocated", "settled") VALUES (E'testbucket'::bytea, E'\\363\\342\\363\\371>+F\\256\\263\\300\\273|\\342N\\347\\014'::bytea,'2019-03-06 08:00:00.000000+00', 3600, 1, 1024, 2024, 3024);
|
||||||
|
INSERT INTO "bucket_storage_tallies" ("bucket_name", "project_id", "interval_start", "inline", "remote", "remote_segments_count", "inline_segments_count", "object_count", "metadata_size") VALUES (E'testbucket'::bytea, E'\\363\\342\\363\\371>+F\\256\\263\\300\\273|\\342N\\347\\014'::bytea,'2019-03-06 08:00:00.000000+00', 4024, 5024, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
-- NEW DATA --
|
||||||
|
|
||||||
|
INSERT INTO "reset_password_tokens" ("secret", "owner_id", "created_at") VALUES (E'\\070\\127\\144\\013\\332\\344\\102\\376\\306\\056\\303\\130\\106\\132\\321\\276\\321\\274\\170\\264\\054\\333\\221\\116\\154\\221\\335\\070\\220\\146\\344\\216'::bytea, E'\\363\\311\\033w\\222\\303Ci\\265\\343U\\303\\312\\204",'::bytea, '2019-05-08 08:28:24.677953+00');
|
@ -532,7 +532,8 @@ To reset your password, click the following link and follow the instructions. &#
|
|||||||
<div style="mso-line-height-rule: exactly;mso-text-raise: 4px;">
|
<div style="mso-line-height-rule: exactly;mso-text-raise: 4px;">
|
||||||
<p class="size-16" style="Margin-top: 0;Margin-bottom: 0;font-family: montserrat,dejavu sans,verdana,sans-serif;font-size: 16px;line-height: 24px;" lang="x-size-16"><span class="font-montserrat">Didn’t request this change?
<br /></span></p>
|
<p class="size-16" style="Margin-top: 0;Margin-bottom: 0;font-family: montserrat,dejavu sans,verdana,sans-serif;font-size: 16px;line-height: 24px;" lang="x-size-16"><span class="font-montserrat">Didn’t request this change?
<br /></span></p>
|
||||||
<p class="size-16" style="Margin-top: 0;Margin-bottom: 0;font-family: montserrat,dejavu sans,verdana,sans-serif;font-size: 16px;line-height: 24px;" lang="x-size-16"><span class="font-montserrat">If you didn’t request a new password
|
<p class="size-16" style="Margin-top: 0;Margin-bottom: 0;font-family: montserrat,dejavu sans,verdana,sans-serif;font-size: 16px;line-height: 24px;" lang="x-size-16"><span class="font-montserrat">If you didn’t request a new password
|
||||||
<a href="mailto:support@storj.io" style="color: #2683ff; text-decoration: none; font-weight: bold">let us know</a><br /></span></p>
|
<a href="{{ .CancelPasswordRecoveryLink }}" style="color: #2683ff; text-decoration: none; font-weight: bold">let us know</a><br /></span></p>
|
||||||
|
<p style="Margin-top: 0;Margin-bottom: 0;font-family: montserrat,dejavu sans,verdana,sans-serif;font-size: 12px;line-height: 24px;" lang="x-size-16"><span class="font-montserrat">Please Note: After clicking on «Let us Know» we will automatically deactivate this reset password link and redirect you to our Support Desk.
<br /></span></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
66
web/satellite/static/resetPassword/success.css
Normal file
66
web/satellite/static/resetPassword/success.css
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*Copyright (C) 2019 Storj Labs, Inc.*/
|
||||||
|
/*See LICENSE for copying information.*/
|
||||||
|
|
||||||
|
.container {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #fff;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container__title {
|
||||||
|
font-family: 'font', sans-serif;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 32px;
|
||||||
|
line-height: 39px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container__info {
|
||||||
|
width: 566px;
|
||||||
|
text-align: center;
|
||||||
|
font-family: 'font', sans-serif;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 26px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container__button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: #2683FF;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 216px;
|
||||||
|
height: 48px;
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container__button p {
|
||||||
|
font-family: 'font', sans-serif;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 23px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container__button:hover {
|
||||||
|
box-shadow: 0px 4px 20px rgba(35, 121, 236, 0.4);
|
||||||
|
}
|
34
web/satellite/static/resetPassword/success.html
Normal file
34
web/satellite/static/resetPassword/success.html
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user