initial v0.8 pre-release

This commit is contained in:
Gani Georgiev
2022-10-30 10:28:14 +02:00
parent 9cbb2e750e
commit 90dba45d7c
388 changed files with 21580 additions and 13603 deletions
+33 -76
View File
@@ -126,38 +126,38 @@ type App interface {
// admin password reset email was successfully sent.
OnMailerAfterAdminResetPasswordSend() *hook.Hook[*MailerAdminEvent]
// OnMailerBeforeUserResetPasswordSend hook is triggered right before
// sending a password reset email to a user.
// OnMailerBeforeRecordResetPasswordSend hook is triggered right before
// sending a password reset email to an auth record.
//
// Could be used to send your own custom email template if
// [hook.StopPropagation] is returned in one of its listeners.
OnMailerBeforeUserResetPasswordSend() *hook.Hook[*MailerUserEvent]
OnMailerBeforeRecordResetPasswordSend() *hook.Hook[*MailerRecordEvent]
// OnMailerAfterUserResetPasswordSend hook is triggered after
// a user password reset email was successfully sent.
OnMailerAfterUserResetPasswordSend() *hook.Hook[*MailerUserEvent]
// OnMailerAfterRecordResetPasswordSend hook is triggered after
// an auth record password reset email was successfully sent.
OnMailerAfterRecordResetPasswordSend() *hook.Hook[*MailerRecordEvent]
// OnMailerBeforeUserVerificationSend hook is triggered right before
// sending a verification email to a user.
// OnMailerBeforeRecordVerificationSend hook is triggered right before
// sending a verification email to an auth record.
//
// Could be used to send your own custom email template if
// [hook.StopPropagation] is returned in one of its listeners.
OnMailerBeforeUserVerificationSend() *hook.Hook[*MailerUserEvent]
OnMailerBeforeRecordVerificationSend() *hook.Hook[*MailerRecordEvent]
// OnMailerAfterUserVerificationSend hook is triggered after a user
// verification email was successfully sent.
OnMailerAfterUserVerificationSend() *hook.Hook[*MailerUserEvent]
// OnMailerAfterRecordVerificationSend hook is triggered after a
// verification email was successfully sent to an auth record.
OnMailerAfterRecordVerificationSend() *hook.Hook[*MailerRecordEvent]
// OnMailerBeforeUserChangeEmailSend hook is triggered right before
// sending a confirmation new address email to a a user.
// OnMailerBeforeRecordChangeEmailSend hook is triggered right before
// sending a confirmation new address email to an auth record.
//
// Could be used to send your own custom email template if
// [hook.StopPropagation] is returned in one of its listeners.
OnMailerBeforeUserChangeEmailSend() *hook.Hook[*MailerUserEvent]
OnMailerBeforeRecordChangeEmailSend() *hook.Hook[*MailerRecordEvent]
// OnMailerAfterUserChangeEmailSend hook is triggered after a user
// change address email was successfully sent.
OnMailerAfterUserChangeEmailSend() *hook.Hook[*MailerUserEvent]
// OnMailerAfterRecordChangeEmailSend hook is triggered after a
// verification email was successfully sent to an auth record.
OnMailerAfterRecordChangeEmailSend() *hook.Hook[*MailerRecordEvent]
// ---------------------------------------------------------------
// Realtime API event hooks
@@ -264,74 +264,31 @@ type App interface {
OnAdminAuthRequest() *hook.Hook[*AdminAuthEvent]
// ---------------------------------------------------------------
// User API event hooks
// Auth Record API event hooks
// ---------------------------------------------------------------
// OnUsersListRequest hook is triggered on each API Users list request.
// OnRecordAuthRequest hook is triggered on each successful API
// record authentication request (sign-in, token refresh, etc.).
//
// Could be used to additionally validate or modify the authenticated
// record data and token.
OnRecordAuthRequest() *hook.Hook[*RecordAuthEvent]
// OnRecordListExternalAuths hook is triggered on each API record external auths list request.
//
// Could be used to validate or modify the response before returning it to the client.
OnUsersListRequest() *hook.Hook[*UsersListEvent]
OnRecordListExternalAuths() *hook.Hook[*RecordListExternalAuthsEvent]
// OnUserViewRequest hook is triggered on each API User view request.
//
// Could be used to validate or modify the response before returning it to the client.
OnUserViewRequest() *hook.Hook[*UserViewEvent]
// OnUserBeforeCreateRequest hook is triggered before each API User
// create request (after request data load and before model persistence).
//
// Could be used to additionally validate the request data or implement
// completely different persistence behavior (returning [hook.StopPropagation]).
OnUserBeforeCreateRequest() *hook.Hook[*UserCreateEvent]
// OnUserAfterCreateRequest hook is triggered after each
// successful API User create request.
OnUserAfterCreateRequest() *hook.Hook[*UserCreateEvent]
// OnUserBeforeUpdateRequest hook is triggered before each API User
// update request (after request data load and before model persistence).
//
// Could be used to additionally validate the request data or implement
// completely different persistence behavior (returning [hook.StopPropagation]).
OnUserBeforeUpdateRequest() *hook.Hook[*UserUpdateEvent]
// OnUserAfterUpdateRequest hook is triggered after each
// successful API User update request.
OnUserAfterUpdateRequest() *hook.Hook[*UserUpdateEvent]
// OnUserBeforeDeleteRequest hook is triggered before each API User
// delete request (after model load and before actual deletion).
//
// Could be used to additionally validate the request data or implement
// completely different delete behavior (returning [hook.StopPropagation]).
OnUserBeforeDeleteRequest() *hook.Hook[*UserDeleteEvent]
// OnUserAfterDeleteRequest hook is triggered after each
// successful API User delete request.
OnUserAfterDeleteRequest() *hook.Hook[*UserDeleteEvent]
// OnUserAuthRequest hook is triggered on each successful API User
// authentication request (sign-in, token refresh, etc.).
//
// Could be used to additionally validate or modify the
// authenticated user data and token.
OnUserAuthRequest() *hook.Hook[*UserAuthEvent]
// OnUserListExternalAuths hook is triggered on each API user's external auths list request.
//
// Could be used to validate or modify the response before returning it to the client.
OnUserListExternalAuths() *hook.Hook[*UserListExternalAuthsEvent]
// OnUserBeforeUnlinkExternalAuthRequest hook is triggered before each API user's
// OnRecordBeforeUnlinkExternalAuthRequest hook is triggered before each API record
// external auth unlink request (after models load and before the actual relation deletion).
//
// Could be used to additionally validate the request data or implement
// completely different delete behavior (returning [hook.StopPropagation]).
OnUserBeforeUnlinkExternalAuthRequest() *hook.Hook[*UserUnlinkExternalAuthEvent]
OnRecordBeforeUnlinkExternalAuthRequest() *hook.Hook[*RecordUnlinkExternalAuthEvent]
// OnUserAfterUnlinkExternalAuthRequest hook is triggered after each
// successful API user's external auth unlink request.
OnUserAfterUnlinkExternalAuthRequest() *hook.Hook[*UserUnlinkExternalAuthEvent]
// OnRecordAfterUnlinkExternalAuthRequest hook is triggered after each
// successful API record external auth unlink request.
OnRecordAfterUnlinkExternalAuthRequest() *hook.Hook[*RecordUnlinkExternalAuthEvent]
// ---------------------------------------------------------------
// Record API event hooks
+46 -94
View File
@@ -52,14 +52,14 @@ type BaseApp struct {
onModelAfterDelete *hook.Hook[*ModelEvent]
// mailer event hooks
onMailerBeforeAdminResetPasswordSend *hook.Hook[*MailerAdminEvent]
onMailerAfterAdminResetPasswordSend *hook.Hook[*MailerAdminEvent]
onMailerBeforeUserResetPasswordSend *hook.Hook[*MailerUserEvent]
onMailerAfterUserResetPasswordSend *hook.Hook[*MailerUserEvent]
onMailerBeforeUserVerificationSend *hook.Hook[*MailerUserEvent]
onMailerAfterUserVerificationSend *hook.Hook[*MailerUserEvent]
onMailerBeforeUserChangeEmailSend *hook.Hook[*MailerUserEvent]
onMailerAfterUserChangeEmailSend *hook.Hook[*MailerUserEvent]
onMailerBeforeAdminResetPasswordSend *hook.Hook[*MailerAdminEvent]
onMailerAfterAdminResetPasswordSend *hook.Hook[*MailerAdminEvent]
onMailerBeforeRecordResetPasswordSend *hook.Hook[*MailerRecordEvent]
onMailerAfterRecordResetPasswordSend *hook.Hook[*MailerRecordEvent]
onMailerBeforeRecordVerificationSend *hook.Hook[*MailerRecordEvent]
onMailerAfterRecordVerificationSend *hook.Hook[*MailerRecordEvent]
onMailerBeforeRecordChangeEmailSend *hook.Hook[*MailerRecordEvent]
onMailerAfterRecordChangeEmailSend *hook.Hook[*MailerRecordEvent]
// realtime api event hooks
onRealtimeConnectRequest *hook.Hook[*RealtimeConnectEvent]
@@ -85,19 +85,11 @@ type BaseApp struct {
onAdminAfterDeleteRequest *hook.Hook[*AdminDeleteEvent]
onAdminAuthRequest *hook.Hook[*AdminAuthEvent]
// user api event hooks
onUsersListRequest *hook.Hook[*UsersListEvent]
onUserViewRequest *hook.Hook[*UserViewEvent]
onUserBeforeCreateRequest *hook.Hook[*UserCreateEvent]
onUserAfterCreateRequest *hook.Hook[*UserCreateEvent]
onUserBeforeUpdateRequest *hook.Hook[*UserUpdateEvent]
onUserAfterUpdateRequest *hook.Hook[*UserUpdateEvent]
onUserBeforeDeleteRequest *hook.Hook[*UserDeleteEvent]
onUserAfterDeleteRequest *hook.Hook[*UserDeleteEvent]
onUserAuthRequest *hook.Hook[*UserAuthEvent]
onUserListExternalAuths *hook.Hook[*UserListExternalAuthsEvent]
onUserBeforeUnlinkExternalAuthRequest *hook.Hook[*UserUnlinkExternalAuthEvent]
onUserAfterUnlinkExternalAuthRequest *hook.Hook[*UserUnlinkExternalAuthEvent]
// user api event hooks
onRecordAuthRequest *hook.Hook[*RecordAuthEvent]
onRecordListExternalAuths *hook.Hook[*RecordListExternalAuthsEvent]
onRecordBeforeUnlinkExternalAuthRequest *hook.Hook[*RecordUnlinkExternalAuthEvent]
onRecordAfterUnlinkExternalAuthRequest *hook.Hook[*RecordUnlinkExternalAuthEvent]
// record api event hooks
onRecordsListRequest *hook.Hook[*RecordsListEvent]
@@ -147,14 +139,14 @@ func NewBaseApp(dataDir string, encryptionEnv string, isDebug bool) *BaseApp {
onModelAfterDelete: &hook.Hook[*ModelEvent]{},
// mailer event hooks
onMailerBeforeAdminResetPasswordSend: &hook.Hook[*MailerAdminEvent]{},
onMailerAfterAdminResetPasswordSend: &hook.Hook[*MailerAdminEvent]{},
onMailerBeforeUserResetPasswordSend: &hook.Hook[*MailerUserEvent]{},
onMailerAfterUserResetPasswordSend: &hook.Hook[*MailerUserEvent]{},
onMailerBeforeUserVerificationSend: &hook.Hook[*MailerUserEvent]{},
onMailerAfterUserVerificationSend: &hook.Hook[*MailerUserEvent]{},
onMailerBeforeUserChangeEmailSend: &hook.Hook[*MailerUserEvent]{},
onMailerAfterUserChangeEmailSend: &hook.Hook[*MailerUserEvent]{},
onMailerBeforeAdminResetPasswordSend: &hook.Hook[*MailerAdminEvent]{},
onMailerAfterAdminResetPasswordSend: &hook.Hook[*MailerAdminEvent]{},
onMailerBeforeRecordResetPasswordSend: &hook.Hook[*MailerRecordEvent]{},
onMailerAfterRecordResetPasswordSend: &hook.Hook[*MailerRecordEvent]{},
onMailerBeforeRecordVerificationSend: &hook.Hook[*MailerRecordEvent]{},
onMailerAfterRecordVerificationSend: &hook.Hook[*MailerRecordEvent]{},
onMailerBeforeRecordChangeEmailSend: &hook.Hook[*MailerRecordEvent]{},
onMailerAfterRecordChangeEmailSend: &hook.Hook[*MailerRecordEvent]{},
// realtime API event hooks
onRealtimeConnectRequest: &hook.Hook[*RealtimeConnectEvent]{},
@@ -181,18 +173,10 @@ func NewBaseApp(dataDir string, encryptionEnv string, isDebug bool) *BaseApp {
onAdminAuthRequest: &hook.Hook[*AdminAuthEvent]{},
// user API event hooks
onUsersListRequest: &hook.Hook[*UsersListEvent]{},
onUserViewRequest: &hook.Hook[*UserViewEvent]{},
onUserBeforeCreateRequest: &hook.Hook[*UserCreateEvent]{},
onUserAfterCreateRequest: &hook.Hook[*UserCreateEvent]{},
onUserBeforeUpdateRequest: &hook.Hook[*UserUpdateEvent]{},
onUserAfterUpdateRequest: &hook.Hook[*UserUpdateEvent]{},
onUserBeforeDeleteRequest: &hook.Hook[*UserDeleteEvent]{},
onUserAfterDeleteRequest: &hook.Hook[*UserDeleteEvent]{},
onUserAuthRequest: &hook.Hook[*UserAuthEvent]{},
onUserListExternalAuths: &hook.Hook[*UserListExternalAuthsEvent]{},
onUserBeforeUnlinkExternalAuthRequest: &hook.Hook[*UserUnlinkExternalAuthEvent]{},
onUserAfterUnlinkExternalAuthRequest: &hook.Hook[*UserUnlinkExternalAuthEvent]{},
onRecordAuthRequest: &hook.Hook[*RecordAuthEvent]{},
onRecordListExternalAuths: &hook.Hook[*RecordListExternalAuthsEvent]{},
onRecordBeforeUnlinkExternalAuthRequest: &hook.Hook[*RecordUnlinkExternalAuthEvent]{},
onRecordAfterUnlinkExternalAuthRequest: &hook.Hook[*RecordUnlinkExternalAuthEvent]{},
// record API event hooks
onRecordsListRequest: &hook.Hook[*RecordsListEvent]{},
@@ -469,28 +453,28 @@ func (app *BaseApp) OnMailerAfterAdminResetPasswordSend() *hook.Hook[*MailerAdmi
return app.onMailerAfterAdminResetPasswordSend
}
func (app *BaseApp) OnMailerBeforeUserResetPasswordSend() *hook.Hook[*MailerUserEvent] {
return app.onMailerBeforeUserResetPasswordSend
func (app *BaseApp) OnMailerBeforeRecordResetPasswordSend() *hook.Hook[*MailerRecordEvent] {
return app.onMailerBeforeRecordResetPasswordSend
}
func (app *BaseApp) OnMailerAfterUserResetPasswordSend() *hook.Hook[*MailerUserEvent] {
return app.onMailerAfterUserResetPasswordSend
func (app *BaseApp) OnMailerAfterRecordResetPasswordSend() *hook.Hook[*MailerRecordEvent] {
return app.onMailerAfterRecordResetPasswordSend
}
func (app *BaseApp) OnMailerBeforeUserVerificationSend() *hook.Hook[*MailerUserEvent] {
return app.onMailerBeforeUserVerificationSend
func (app *BaseApp) OnMailerBeforeRecordVerificationSend() *hook.Hook[*MailerRecordEvent] {
return app.onMailerBeforeRecordVerificationSend
}
func (app *BaseApp) OnMailerAfterUserVerificationSend() *hook.Hook[*MailerUserEvent] {
return app.onMailerAfterUserVerificationSend
func (app *BaseApp) OnMailerAfterRecordVerificationSend() *hook.Hook[*MailerRecordEvent] {
return app.onMailerAfterRecordVerificationSend
}
func (app *BaseApp) OnMailerBeforeUserChangeEmailSend() *hook.Hook[*MailerUserEvent] {
return app.onMailerBeforeUserChangeEmailSend
func (app *BaseApp) OnMailerBeforeRecordChangeEmailSend() *hook.Hook[*MailerRecordEvent] {
return app.onMailerBeforeRecordChangeEmailSend
}
func (app *BaseApp) OnMailerAfterUserChangeEmailSend() *hook.Hook[*MailerUserEvent] {
return app.onMailerAfterUserChangeEmailSend
func (app *BaseApp) OnMailerAfterRecordChangeEmailSend() *hook.Hook[*MailerRecordEvent] {
return app.onMailerAfterRecordChangeEmailSend
}
// -------------------------------------------------------------------
@@ -574,55 +558,23 @@ func (app *BaseApp) OnAdminAuthRequest() *hook.Hook[*AdminAuthEvent] {
}
// -------------------------------------------------------------------
// User API event hooks
// Auth Record API event hooks
// -------------------------------------------------------------------
func (app *BaseApp) OnUsersListRequest() *hook.Hook[*UsersListEvent] {
return app.onUsersListRequest
func (app *BaseApp) OnRecordAuthRequest() *hook.Hook[*RecordAuthEvent] {
return app.onRecordAuthRequest
}
func (app *BaseApp) OnUserViewRequest() *hook.Hook[*UserViewEvent] {
return app.onUserViewRequest
func (app *BaseApp) OnRecordListExternalAuths() *hook.Hook[*RecordListExternalAuthsEvent] {
return app.onRecordListExternalAuths
}
func (app *BaseApp) OnUserBeforeCreateRequest() *hook.Hook[*UserCreateEvent] {
return app.onUserBeforeCreateRequest
func (app *BaseApp) OnRecordBeforeUnlinkExternalAuthRequest() *hook.Hook[*RecordUnlinkExternalAuthEvent] {
return app.onRecordBeforeUnlinkExternalAuthRequest
}
func (app *BaseApp) OnUserAfterCreateRequest() *hook.Hook[*UserCreateEvent] {
return app.onUserAfterCreateRequest
}
func (app *BaseApp) OnUserBeforeUpdateRequest() *hook.Hook[*UserUpdateEvent] {
return app.onUserBeforeUpdateRequest
}
func (app *BaseApp) OnUserAfterUpdateRequest() *hook.Hook[*UserUpdateEvent] {
return app.onUserAfterUpdateRequest
}
func (app *BaseApp) OnUserBeforeDeleteRequest() *hook.Hook[*UserDeleteEvent] {
return app.onUserBeforeDeleteRequest
}
func (app *BaseApp) OnUserAfterDeleteRequest() *hook.Hook[*UserDeleteEvent] {
return app.onUserAfterDeleteRequest
}
func (app *BaseApp) OnUserAuthRequest() *hook.Hook[*UserAuthEvent] {
return app.onUserAuthRequest
}
func (app *BaseApp) OnUserListExternalAuths() *hook.Hook[*UserListExternalAuthsEvent] {
return app.onUserListExternalAuths
}
func (app *BaseApp) OnUserBeforeUnlinkExternalAuthRequest() *hook.Hook[*UserUnlinkExternalAuthEvent] {
return app.onUserBeforeUnlinkExternalAuthRequest
}
func (app *BaseApp) OnUserAfterUnlinkExternalAuthRequest() *hook.Hook[*UserUnlinkExternalAuthEvent] {
return app.onUserAfterUnlinkExternalAuthRequest
func (app *BaseApp) OnRecordAfterUnlinkExternalAuthRequest() *hook.Hook[*RecordUnlinkExternalAuthEvent] {
return app.onRecordAfterUnlinkExternalAuthRequest
}
// -------------------------------------------------------------------
+36 -36
View File
@@ -195,28 +195,28 @@ func TestBaseAppGetters(t *testing.T) {
t.Fatalf("Getter app.OnMailerAfterAdminResetPasswordSend does not match or nil (%v vs %v)", app.OnMailerAfterAdminResetPasswordSend(), app.onMailerAfterAdminResetPasswordSend)
}
if app.onMailerBeforeUserResetPasswordSend != app.OnMailerBeforeUserResetPasswordSend() || app.OnMailerBeforeUserResetPasswordSend() == nil {
t.Fatalf("Getter app.OnMailerBeforeUserResetPasswordSend does not match or nil (%v vs %v)", app.OnMailerBeforeUserResetPasswordSend(), app.onMailerBeforeUserResetPasswordSend)
if app.onMailerBeforeRecordResetPasswordSend != app.OnMailerBeforeRecordResetPasswordSend() || app.OnMailerBeforeRecordResetPasswordSend() == nil {
t.Fatalf("Getter app.OnMailerBeforeRecordResetPasswordSend does not match or nil (%v vs %v)", app.OnMailerBeforeRecordResetPasswordSend(), app.onMailerBeforeRecordResetPasswordSend)
}
if app.onMailerAfterUserResetPasswordSend != app.OnMailerAfterUserResetPasswordSend() || app.OnMailerAfterUserResetPasswordSend() == nil {
t.Fatalf("Getter app.OnMailerAfterUserResetPasswordSend does not match or nil (%v vs %v)", app.OnMailerAfterUserResetPasswordSend(), app.onMailerAfterUserResetPasswordSend)
if app.onMailerAfterRecordResetPasswordSend != app.OnMailerAfterRecordResetPasswordSend() || app.OnMailerAfterRecordResetPasswordSend() == nil {
t.Fatalf("Getter app.OnMailerAfterRecordResetPasswordSend does not match or nil (%v vs %v)", app.OnMailerAfterRecordResetPasswordSend(), app.onMailerAfterRecordResetPasswordSend)
}
if app.onMailerBeforeUserVerificationSend != app.OnMailerBeforeUserVerificationSend() || app.OnMailerBeforeUserVerificationSend() == nil {
t.Fatalf("Getter app.OnMailerBeforeUserVerificationSend does not match or nil (%v vs %v)", app.OnMailerBeforeUserVerificationSend(), app.onMailerBeforeUserVerificationSend)
if app.onMailerBeforeRecordVerificationSend != app.OnMailerBeforeRecordVerificationSend() || app.OnMailerBeforeRecordVerificationSend() == nil {
t.Fatalf("Getter app.OnMailerBeforeRecordVerificationSend does not match or nil (%v vs %v)", app.OnMailerBeforeRecordVerificationSend(), app.onMailerBeforeRecordVerificationSend)
}
if app.onMailerAfterUserVerificationSend != app.OnMailerAfterUserVerificationSend() || app.OnMailerAfterUserVerificationSend() == nil {
t.Fatalf("Getter app.OnMailerAfterUserVerificationSend does not match or nil (%v vs %v)", app.OnMailerAfterUserVerificationSend(), app.onMailerAfterUserVerificationSend)
if app.onMailerAfterRecordVerificationSend != app.OnMailerAfterRecordVerificationSend() || app.OnMailerAfterRecordVerificationSend() == nil {
t.Fatalf("Getter app.OnMailerAfterRecordVerificationSend does not match or nil (%v vs %v)", app.OnMailerAfterRecordVerificationSend(), app.onMailerAfterRecordVerificationSend)
}
if app.onMailerBeforeUserChangeEmailSend != app.OnMailerBeforeUserChangeEmailSend() || app.OnMailerBeforeUserChangeEmailSend() == nil {
t.Fatalf("Getter app.OnMailerBeforeUserChangeEmailSend does not match or nil (%v vs %v)", app.OnMailerBeforeUserChangeEmailSend(), app.onMailerBeforeUserChangeEmailSend)
if app.onMailerBeforeRecordChangeEmailSend != app.OnMailerBeforeRecordChangeEmailSend() || app.OnMailerBeforeRecordChangeEmailSend() == nil {
t.Fatalf("Getter app.OnMailerBeforeRecordChangeEmailSend does not match or nil (%v vs %v)", app.OnMailerBeforeRecordChangeEmailSend(), app.onMailerBeforeRecordChangeEmailSend)
}
if app.onMailerAfterUserChangeEmailSend != app.OnMailerAfterUserChangeEmailSend() || app.OnMailerAfterUserChangeEmailSend() == nil {
t.Fatalf("Getter app.OnMailerAfterUserChangeEmailSend does not match or nil (%v vs %v)", app.OnMailerAfterUserChangeEmailSend(), app.onMailerAfterUserChangeEmailSend)
if app.onMailerAfterRecordChangeEmailSend != app.OnMailerAfterRecordChangeEmailSend() || app.OnMailerAfterRecordChangeEmailSend() == nil {
t.Fatalf("Getter app.OnMailerAfterRecordChangeEmailSend does not match or nil (%v vs %v)", app.OnMailerAfterRecordChangeEmailSend(), app.onMailerAfterRecordChangeEmailSend)
}
if app.onRealtimeConnectRequest != app.OnRealtimeConnectRequest() || app.OnRealtimeConnectRequest() == nil {
@@ -283,52 +283,52 @@ func TestBaseAppGetters(t *testing.T) {
t.Fatalf("Getter app.OnAdminAuthRequest does not match or nil (%v vs %v)", app.OnAdminAuthRequest(), app.onAdminAuthRequest)
}
if app.onUsersListRequest != app.OnUsersListRequest() || app.OnUsersListRequest() == nil {
t.Fatalf("Getter app.OnUsersListRequest does not match or nil (%v vs %v)", app.OnUsersListRequest(), app.onUsersListRequest)
if app.onRecordsListRequest != app.OnRecordsListRequest() || app.OnRecordsListRequest() == nil {
t.Fatalf("Getter app.OnRecordsListRequest does not match or nil (%v vs %v)", app.OnRecordsListRequest(), app.onRecordsListRequest)
}
if app.onUserViewRequest != app.OnUserViewRequest() || app.OnUserViewRequest() == nil {
t.Fatalf("Getter app.OnUserViewRequest does not match or nil (%v vs %v)", app.OnUserViewRequest(), app.onUserViewRequest)
if app.onRecordViewRequest != app.OnRecordViewRequest() || app.OnRecordViewRequest() == nil {
t.Fatalf("Getter app.OnRecordViewRequest does not match or nil (%v vs %v)", app.OnRecordViewRequest(), app.onRecordViewRequest)
}
if app.onUserBeforeCreateRequest != app.OnUserBeforeCreateRequest() || app.OnUserBeforeCreateRequest() == nil {
t.Fatalf("Getter app.OnUserBeforeCreateRequest does not match or nil (%v vs %v)", app.OnUserBeforeCreateRequest(), app.onUserBeforeCreateRequest)
if app.onRecordBeforeCreateRequest != app.OnRecordBeforeCreateRequest() || app.OnRecordBeforeCreateRequest() == nil {
t.Fatalf("Getter app.OnRecordBeforeCreateRequest does not match or nil (%v vs %v)", app.OnRecordBeforeCreateRequest(), app.onRecordBeforeCreateRequest)
}
if app.onUserAfterCreateRequest != app.OnUserAfterCreateRequest() || app.OnUserAfterCreateRequest() == nil {
t.Fatalf("Getter app.OnUserAfterCreateRequest does not match or nil (%v vs %v)", app.OnUserAfterCreateRequest(), app.onUserAfterCreateRequest)
if app.onRecordAfterCreateRequest != app.OnRecordAfterCreateRequest() || app.OnRecordAfterCreateRequest() == nil {
t.Fatalf("Getter app.OnRecordAfterCreateRequest does not match or nil (%v vs %v)", app.OnRecordAfterCreateRequest(), app.onRecordAfterCreateRequest)
}
if app.onUserBeforeUpdateRequest != app.OnUserBeforeUpdateRequest() || app.OnUserBeforeUpdateRequest() == nil {
t.Fatalf("Getter app.OnUserBeforeUpdateRequest does not match or nil (%v vs %v)", app.OnUserBeforeUpdateRequest(), app.onUserBeforeUpdateRequest)
if app.onRecordBeforeUpdateRequest != app.OnRecordBeforeUpdateRequest() || app.OnRecordBeforeUpdateRequest() == nil {
t.Fatalf("Getter app.OnRecordBeforeUpdateRequest does not match or nil (%v vs %v)", app.OnRecordBeforeUpdateRequest(), app.onRecordBeforeUpdateRequest)
}
if app.onUserAfterUpdateRequest != app.OnUserAfterUpdateRequest() || app.OnUserAfterUpdateRequest() == nil {
t.Fatalf("Getter app.OnUserAfterUpdateRequest does not match or nil (%v vs %v)", app.OnUserAfterUpdateRequest(), app.onUserAfterUpdateRequest)
if app.onRecordAfterUpdateRequest != app.OnRecordAfterUpdateRequest() || app.OnRecordAfterUpdateRequest() == nil {
t.Fatalf("Getter app.OnRecordAfterUpdateRequest does not match or nil (%v vs %v)", app.OnRecordAfterUpdateRequest(), app.onRecordAfterUpdateRequest)
}
if app.onUserBeforeDeleteRequest != app.OnUserBeforeDeleteRequest() || app.OnUserBeforeDeleteRequest() == nil {
t.Fatalf("Getter app.OnUserBeforeDeleteRequest does not match or nil (%v vs %v)", app.OnUserBeforeDeleteRequest(), app.onUserBeforeDeleteRequest)
if app.onRecordBeforeDeleteRequest != app.OnRecordBeforeDeleteRequest() || app.OnRecordBeforeDeleteRequest() == nil {
t.Fatalf("Getter app.OnRecordBeforeDeleteRequest does not match or nil (%v vs %v)", app.OnRecordBeforeDeleteRequest(), app.onRecordBeforeDeleteRequest)
}
if app.onUserAfterDeleteRequest != app.OnUserAfterDeleteRequest() || app.OnUserAfterDeleteRequest() == nil {
t.Fatalf("Getter app.OnUserAfterDeleteRequest does not match or nil (%v vs %v)", app.OnUserAfterDeleteRequest(), app.onUserAfterDeleteRequest)
if app.onRecordAfterDeleteRequest != app.OnRecordAfterDeleteRequest() || app.OnRecordAfterDeleteRequest() == nil {
t.Fatalf("Getter app.OnRecordAfterDeleteRequest does not match or nil (%v vs %v)", app.OnRecordAfterDeleteRequest(), app.onRecordAfterDeleteRequest)
}
if app.onUserAuthRequest != app.OnUserAuthRequest() || app.OnUserAuthRequest() == nil {
t.Fatalf("Getter app.OnUserAuthRequest does not match or nil (%v vs %v)", app.OnUserAuthRequest(), app.onUserAuthRequest)
if app.onRecordAuthRequest != app.OnRecordAuthRequest() || app.OnRecordAuthRequest() == nil {
t.Fatalf("Getter app.OnRecordAuthRequest does not match or nil (%v vs %v)", app.OnRecordAuthRequest(), app.onRecordAuthRequest)
}
if app.onUserListExternalAuths != app.OnUserListExternalAuths() || app.OnUserListExternalAuths() == nil {
t.Fatalf("Getter app.OnUserListExternalAuths does not match or nil (%v vs %v)", app.OnUserListExternalAuths(), app.onUserListExternalAuths)
if app.onRecordListExternalAuths != app.OnRecordListExternalAuths() || app.OnRecordListExternalAuths() == nil {
t.Fatalf("Getter app.OnRecordListExternalAuths does not match or nil (%v vs %v)", app.OnRecordListExternalAuths(), app.onRecordListExternalAuths)
}
if app.onUserBeforeUnlinkExternalAuthRequest != app.OnUserBeforeUnlinkExternalAuthRequest() || app.OnUserBeforeUnlinkExternalAuthRequest() == nil {
t.Fatalf("Getter app.OnUserBeforeUnlinkExternalAuthRequest does not match or nil (%v vs %v)", app.OnUserBeforeUnlinkExternalAuthRequest(), app.onUserBeforeUnlinkExternalAuthRequest)
if app.onRecordBeforeUnlinkExternalAuthRequest != app.OnRecordBeforeUnlinkExternalAuthRequest() || app.OnRecordBeforeUnlinkExternalAuthRequest() == nil {
t.Fatalf("Getter app.OnRecordBeforeUnlinkExternalAuthRequest does not match or nil (%v vs %v)", app.OnRecordBeforeUnlinkExternalAuthRequest(), app.onRecordBeforeUnlinkExternalAuthRequest)
}
if app.onUserAfterUnlinkExternalAuthRequest != app.OnUserAfterUnlinkExternalAuthRequest() || app.OnUserAfterUnlinkExternalAuthRequest() == nil {
t.Fatalf("Getter app.OnUserAfterUnlinkExternalAuthRequest does not match or nil (%v vs %v)", app.OnUserAfterUnlinkExternalAuthRequest(), app.onUserAfterUnlinkExternalAuthRequest)
if app.onRecordAfterUnlinkExternalAuthRequest != app.OnRecordAfterUnlinkExternalAuthRequest() || app.OnRecordAfterUnlinkExternalAuthRequest() == nil {
t.Fatalf("Getter app.OnRecordAfterUnlinkExternalAuthRequest does not match or nil (%v vs %v)", app.OnRecordAfterUnlinkExternalAuthRequest(), app.onRecordAfterUnlinkExternalAuthRequest)
}
if app.onRecordsListRequest != app.OnRecordsListRequest() || app.OnRecordsListRequest() == nil {
+9 -35
View File
@@ -33,9 +33,9 @@ type ModelEvent struct {
// Mailer events data
// -------------------------------------------------------------------
type MailerUserEvent struct {
type MailerRecordEvent struct {
MailClient mailer.Mailer
User *models.User
Record *models.Record
Meta map[string]any
}
@@ -143,51 +143,25 @@ type AdminAuthEvent struct {
}
// -------------------------------------------------------------------
// User API events data
// Auth Record API events data
// -------------------------------------------------------------------
type UsersListEvent struct {
type RecordAuthEvent struct {
HttpContext echo.Context
Users []*models.User
Result *search.Result
}
type UserViewEvent struct {
HttpContext echo.Context
User *models.User
}
type UserCreateEvent struct {
HttpContext echo.Context
User *models.User
}
type UserUpdateEvent struct {
HttpContext echo.Context
User *models.User
}
type UserDeleteEvent struct {
HttpContext echo.Context
User *models.User
}
type UserAuthEvent struct {
HttpContext echo.Context
User *models.User
Record *models.Record
Token string
Meta any
}
type UserListExternalAuthsEvent struct {
type RecordListExternalAuthsEvent struct {
HttpContext echo.Context
User *models.User
Record *models.Record
ExternalAuths []*models.ExternalAuth
}
type UserUnlinkExternalAuthEvent struct {
type RecordUnlinkExternalAuthEvent struct {
HttpContext echo.Context
User *models.User
Record *models.Record
ExternalAuth *models.ExternalAuth
}
+49 -74
View File
@@ -23,14 +23,16 @@ type Settings struct {
Smtp SmtpConfig `form:"smtp" json:"smtp"`
S3 S3Config `form:"s3" json:"s3"`
AdminAuthToken TokenConfig `form:"adminAuthToken" json:"adminAuthToken"`
AdminPasswordResetToken TokenConfig `form:"adminPasswordResetToken" json:"adminPasswordResetToken"`
UserAuthToken TokenConfig `form:"userAuthToken" json:"userAuthToken"`
UserPasswordResetToken TokenConfig `form:"userPasswordResetToken" json:"userPasswordResetToken"`
UserEmailChangeToken TokenConfig `form:"userEmailChangeToken" json:"userEmailChangeToken"`
UserVerificationToken TokenConfig `form:"userVerificationToken" json:"userVerificationToken"`
AdminAuthToken TokenConfig `form:"adminAuthToken" json:"adminAuthToken"`
AdminPasswordResetToken TokenConfig `form:"adminPasswordResetToken" json:"adminPasswordResetToken"`
RecordAuthToken TokenConfig `form:"recordAuthToken" json:"recordAuthToken"`
RecordPasswordResetToken TokenConfig `form:"recordPasswordResetToken" json:"recordPasswordResetToken"`
RecordEmailChangeToken TokenConfig `form:"recordEmailChangeToken" json:"recordEmailChangeToken"`
RecordVerificationToken TokenConfig `form:"recordVerificationToken" json:"recordVerificationToken"`
// Deprecated: Will be removed in v0.9!
EmailAuth EmailAuthConfig `form:"emailAuth" json:"emailAuth"`
EmailAuth EmailAuthConfig `form:"emailAuth" json:"emailAuth"`
GoogleAuth AuthProviderConfig `form:"googleAuth" json:"googleAuth"`
FacebookAuth AuthProviderConfig `form:"facebookAuth" json:"facebookAuth"`
GithubAuth AuthProviderConfig `form:"githubAuth" json:"githubAuth"`
@@ -52,9 +54,8 @@ func NewSettings() *Settings {
ResetPasswordTemplate: defaultResetPasswordTemplate,
ConfirmEmailChangeTemplate: defaultConfirmEmailChangeTemplate,
},
Logs: LogsConfig{
MaxDays: 7,
MaxDays: 5,
},
Smtp: SmtpConfig{
Enabled: false,
@@ -72,49 +73,39 @@ func NewSettings() *Settings {
Secret: security.RandomString(50),
Duration: 1800, // 30 minutes,
},
UserAuthToken: TokenConfig{
RecordAuthToken: TokenConfig{
Secret: security.RandomString(50),
Duration: 1209600, // 14 days,
},
UserPasswordResetToken: TokenConfig{
RecordPasswordResetToken: TokenConfig{
Secret: security.RandomString(50),
Duration: 1800, // 30 minutes,
},
UserVerificationToken: TokenConfig{
RecordVerificationToken: TokenConfig{
Secret: security.RandomString(50),
Duration: 604800, // 7 days,
},
UserEmailChangeToken: TokenConfig{
RecordEmailChangeToken: TokenConfig{
Secret: security.RandomString(50),
Duration: 1800, // 30 minutes,
},
EmailAuth: EmailAuthConfig{
Enabled: true,
MinPasswordLength: 8,
},
GoogleAuth: AuthProviderConfig{
Enabled: false,
AllowRegistrations: true,
Enabled: false,
},
FacebookAuth: AuthProviderConfig{
Enabled: false,
AllowRegistrations: true,
Enabled: false,
},
GithubAuth: AuthProviderConfig{
Enabled: false,
AllowRegistrations: true,
Enabled: false,
},
GitlabAuth: AuthProviderConfig{
Enabled: false,
AllowRegistrations: true,
Enabled: false,
},
DiscordAuth: AuthProviderConfig{
Enabled: false,
AllowRegistrations: true,
Enabled: false,
},
TwitterAuth: AuthProviderConfig{
Enabled: false,
AllowRegistrations: true,
Enabled: false,
},
}
}
@@ -129,13 +120,12 @@ func (s *Settings) Validate() error {
validation.Field(&s.Logs),
validation.Field(&s.AdminAuthToken),
validation.Field(&s.AdminPasswordResetToken),
validation.Field(&s.UserAuthToken),
validation.Field(&s.UserPasswordResetToken),
validation.Field(&s.UserEmailChangeToken),
validation.Field(&s.UserVerificationToken),
validation.Field(&s.RecordAuthToken),
validation.Field(&s.RecordPasswordResetToken),
validation.Field(&s.RecordEmailChangeToken),
validation.Field(&s.RecordVerificationToken),
validation.Field(&s.Smtp),
validation.Field(&s.S3),
validation.Field(&s.EmailAuth),
validation.Field(&s.GoogleAuth),
validation.Field(&s.FacebookAuth),
validation.Field(&s.GithubAuth),
@@ -182,10 +172,10 @@ func (s *Settings) RedactClone() (*Settings, error) {
&clone.S3.Secret,
&clone.AdminAuthToken.Secret,
&clone.AdminPasswordResetToken.Secret,
&clone.UserAuthToken.Secret,
&clone.UserPasswordResetToken.Secret,
&clone.UserEmailChangeToken.Secret,
&clone.UserVerificationToken.Secret,
&clone.RecordAuthToken.Secret,
&clone.RecordPasswordResetToken.Secret,
&clone.RecordEmailChangeToken.Secret,
&clone.RecordVerificationToken.Secret,
&clone.GoogleAuth.ClientSecret,
&clone.FacebookAuth.ClientSecret,
&clone.GithubAuth.ClientSecret,
@@ -407,43 +397,13 @@ func (c LogsConfig) Validate() error {
// -------------------------------------------------------------------
type EmailAuthConfig struct {
Enabled bool `form:"enabled" json:"enabled"`
ExceptDomains []string `form:"exceptDomains" json:"exceptDomains"`
OnlyDomains []string `form:"onlyDomains" json:"onlyDomains"`
MinPasswordLength int `form:"minPasswordLength" json:"minPasswordLength"`
}
// Validate makes `EmailAuthConfig` validatable by implementing [validation.Validatable] interface.
func (c EmailAuthConfig) Validate() error {
return validation.ValidateStruct(&c,
validation.Field(
&c.ExceptDomains,
validation.When(len(c.OnlyDomains) > 0, validation.Empty).Else(validation.Each(is.Domain)),
),
validation.Field(
&c.OnlyDomains,
validation.When(len(c.ExceptDomains) > 0, validation.Empty).Else(validation.Each(is.Domain)),
),
validation.Field(
&c.MinPasswordLength,
validation.When(c.Enabled, validation.Required),
validation.Min(5),
validation.Max(100),
),
)
}
// -------------------------------------------------------------------
type AuthProviderConfig struct {
Enabled bool `form:"enabled" json:"enabled"`
AllowRegistrations bool `form:"allowRegistrations" json:"allowRegistrations"`
ClientId string `form:"clientId" json:"clientId,omitempty"`
ClientSecret string `form:"clientSecret" json:"clientSecret,omitempty"`
AuthUrl string `form:"authUrl" json:"authUrl,omitempty"`
TokenUrl string `form:"tokenUrl" json:"tokenUrl,omitempty"`
UserApiUrl string `form:"userApiUrl" json:"userApiUrl,omitempty"`
Enabled bool `form:"enabled" json:"enabled"`
ClientId string `form:"clientId" json:"clientId,omitempty"`
ClientSecret string `form:"clientSecret" json:"clientSecret,omitempty"`
AuthUrl string `form:"authUrl" json:"authUrl,omitempty"`
TokenUrl string `form:"tokenUrl" json:"tokenUrl,omitempty"`
UserApiUrl string `form:"userApiUrl" json:"userApiUrl,omitempty"`
}
// Validate makes `ProviderConfig` validatable by implementing [validation.Validatable] interface.
@@ -485,3 +445,18 @@ func (c AuthProviderConfig) SetupProvider(provider auth.Provider) error {
return nil
}
// -------------------------------------------------------------------
// Deprecated: Will be removed in v0.9!
type EmailAuthConfig struct {
Enabled bool `form:"enabled" json:"enabled"`
ExceptDomains []string `form:"exceptDomains" json:"exceptDomains"`
OnlyDomains []string `form:"onlyDomains" json:"onlyDomains"`
MinPasswordLength int `form:"minPasswordLength" json:"minPasswordLength"`
}
// Deprecated: Will be removed in v0.9!
func (c EmailAuthConfig) Validate() error {
return nil
}
+3 -3
View File
@@ -20,7 +20,7 @@ var defaultVerificationTemplate = EmailTemplate{
Thanks,<br/>
` + EmailPlaceholderAppName + ` team
</p>`,
ActionUrl: EmailPlaceholderAppUrl + "/_/#/users/confirm-verification/" + EmailPlaceholderToken,
ActionUrl: EmailPlaceholderAppUrl + "/_/#/auth/confirm-verification/" + EmailPlaceholderToken,
}
var defaultResetPasswordTemplate = EmailTemplate{
@@ -35,7 +35,7 @@ var defaultResetPasswordTemplate = EmailTemplate{
Thanks,<br/>
` + EmailPlaceholderAppName + ` team
</p>`,
ActionUrl: EmailPlaceholderAppUrl + "/_/#/users/confirm-password-reset/" + EmailPlaceholderToken,
ActionUrl: EmailPlaceholderAppUrl + "/_/#/auth/confirm-password-reset/" + EmailPlaceholderToken,
}
var defaultConfirmEmailChangeTemplate = EmailTemplate{
@@ -50,5 +50,5 @@ var defaultConfirmEmailChangeTemplate = EmailTemplate{
Thanks,<br/>
` + EmailPlaceholderAppName + ` team
</p>`,
ActionUrl: EmailPlaceholderAppUrl + "/_/#/users/confirm-email-change/" + EmailPlaceholderToken,
ActionUrl: EmailPlaceholderAppUrl + "/_/#/auth/confirm-email-change/" + EmailPlaceholderToken,
}
+40 -103
View File
@@ -23,12 +23,10 @@ func TestSettingsValidate(t *testing.T) {
s.S3.Endpoint = "invalid"
s.AdminAuthToken.Duration = -10
s.AdminPasswordResetToken.Duration = -10
s.UserAuthToken.Duration = -10
s.UserPasswordResetToken.Duration = -10
s.UserEmailChangeToken.Duration = -10
s.UserVerificationToken.Duration = -10
s.EmailAuth.Enabled = true
s.EmailAuth.MinPasswordLength = -10
s.RecordAuthToken.Duration = -10
s.RecordPasswordResetToken.Duration = -10
s.RecordEmailChangeToken.Duration = -10
s.RecordVerificationToken.Duration = -10
s.GoogleAuth.Enabled = true
s.GoogleAuth.ClientId = ""
s.FacebookAuth.Enabled = true
@@ -55,16 +53,16 @@ func TestSettingsValidate(t *testing.T) {
`"s3":{`,
`"adminAuthToken":{`,
`"adminPasswordResetToken":{`,
`"userAuthToken":{`,
`"userPasswordResetToken":{`,
`"userEmailChangeToken":{`,
`"userVerificationToken":{`,
`"emailAuth":{`,
`"recordAuthToken":{`,
`"recordPasswordResetToken":{`,
`"recordEmailChangeToken":{`,
`"recordVerificationToken":{`,
`"googleAuth":{`,
`"facebookAuth":{`,
`"githubAuth":{`,
`"gitlabAuth":{`,
`"discordAuth":{`,
`"twitterAuth":{`,
}
errBytes, _ := json.Marshal(err)
@@ -89,12 +87,10 @@ func TestSettingsMerge(t *testing.T) {
s2.S3.Endpoint = "test"
s2.AdminAuthToken.Duration = 1
s2.AdminPasswordResetToken.Duration = 2
s2.UserAuthToken.Duration = 3
s2.UserPasswordResetToken.Duration = 4
s2.UserEmailChangeToken.Duration = 5
s2.UserVerificationToken.Duration = 6
s2.EmailAuth.Enabled = false
s2.EmailAuth.MinPasswordLength = 30
s2.RecordAuthToken.Duration = 3
s2.RecordPasswordResetToken.Duration = 4
s2.RecordEmailChangeToken.Duration = 5
s2.RecordVerificationToken.Duration = 6
s2.GoogleAuth.Enabled = true
s2.GoogleAuth.ClientId = "google_test"
s2.FacebookAuth.Enabled = true
@@ -164,10 +160,10 @@ func TestSettingsRedactClone(t *testing.T) {
s1.S3.Secret = "test123"
s1.AdminAuthToken.Secret = "test123"
s1.AdminPasswordResetToken.Secret = "test123"
s1.UserAuthToken.Secret = "test123"
s1.UserPasswordResetToken.Secret = "test123"
s1.UserEmailChangeToken.Secret = "test123"
s1.UserVerificationToken.Secret = "test123"
s1.RecordAuthToken.Secret = "test123"
s1.RecordPasswordResetToken.Secret = "test123"
s1.RecordEmailChangeToken.Secret = "test123"
s1.RecordVerificationToken.Secret = "test123"
s1.GoogleAuth.ClientSecret = "test123"
s1.FacebookAuth.ClientSecret = "test123"
s1.GithubAuth.ClientSecret = "test123"
@@ -185,10 +181,10 @@ func TestSettingsRedactClone(t *testing.T) {
t.Fatal(err)
}
expected := `{"meta":{"appName":"test123","appUrl":"http://localhost:8090","hideControls":false,"senderName":"Support","senderAddress":"support@example.com","verificationTemplate":{"body":"\u003cp\u003eHello,\u003c/p\u003e\n\u003cp\u003eThank you for joining us at {APP_NAME}.\u003c/p\u003e\n\u003cp\u003eClick on the button below to verify your email address.\u003c/p\u003e\n\u003cp\u003e\n \u003ca class=\"btn\" href=\"{ACTION_URL}\" target=\"_blank\" rel=\"noopener\"\u003eVerify\u003c/a\u003e\n\u003c/p\u003e\n\u003cp\u003e\n Thanks,\u003cbr/\u003e\n {APP_NAME} team\n\u003c/p\u003e","subject":"Verify your {APP_NAME} email","actionUrl":"{APP_URL}/_/#/users/confirm-verification/{TOKEN}"},"resetPasswordTemplate":{"body":"\u003cp\u003eHello,\u003c/p\u003e\n\u003cp\u003eClick on the button below to reset your password.\u003c/p\u003e\n\u003cp\u003e\n \u003ca class=\"btn\" href=\"{ACTION_URL}\" target=\"_blank\" rel=\"noopener\"\u003eReset password\u003c/a\u003e\n\u003c/p\u003e\n\u003cp\u003e\u003ci\u003eIf you didn't ask to reset your password, you can ignore this email.\u003c/i\u003e\u003c/p\u003e\n\u003cp\u003e\n Thanks,\u003cbr/\u003e\n {APP_NAME} team\n\u003c/p\u003e","subject":"Reset your {APP_NAME} password","actionUrl":"{APP_URL}/_/#/users/confirm-password-reset/{TOKEN}"},"confirmEmailChangeTemplate":{"body":"\u003cp\u003eHello,\u003c/p\u003e\n\u003cp\u003eClick on the button below to confirm your new email address.\u003c/p\u003e\n\u003cp\u003e\n \u003ca class=\"btn\" href=\"{ACTION_URL}\" target=\"_blank\" rel=\"noopener\"\u003eConfirm new email\u003c/a\u003e\n\u003c/p\u003e\n\u003cp\u003e\u003ci\u003eIf you didn't ask to change your email address, you can ignore this email.\u003c/i\u003e\u003c/p\u003e\n\u003cp\u003e\n Thanks,\u003cbr/\u003e\n {APP_NAME} team\n\u003c/p\u003e","subject":"Confirm your {APP_NAME} new email address","actionUrl":"{APP_URL}/_/#/users/confirm-email-change/{TOKEN}"}},"logs":{"maxDays":7},"smtp":{"enabled":false,"host":"smtp.example.com","port":587,"username":"","password":"******","tls":true},"s3":{"enabled":false,"bucket":"","region":"","endpoint":"","accessKey":"","secret":"******","forcePathStyle":false},"adminAuthToken":{"secret":"******","duration":1209600},"adminPasswordResetToken":{"secret":"******","duration":1800},"userAuthToken":{"secret":"******","duration":1209600},"userPasswordResetToken":{"secret":"******","duration":1800},"userEmailChangeToken":{"secret":"******","duration":1800},"userVerificationToken":{"secret":"******","duration":604800},"emailAuth":{"enabled":true,"exceptDomains":null,"onlyDomains":null,"minPasswordLength":8},"googleAuth":{"enabled":false,"allowRegistrations":true,"clientSecret":"******"},"facebookAuth":{"enabled":false,"allowRegistrations":true,"clientSecret":"******"},"githubAuth":{"enabled":false,"allowRegistrations":true,"clientSecret":"******"},"gitlabAuth":{"enabled":false,"allowRegistrations":true,"clientSecret":"******"},"discordAuth":{"enabled":false,"allowRegistrations":true,"clientSecret":"******"},"twitterAuth":{"enabled":false,"allowRegistrations":true,"clientSecret":"******"}}`
expected := `{"meta":{"appName":"test123","appUrl":"http://localhost:8090","hideControls":false,"senderName":"Support","senderAddress":"support@example.com","verificationTemplate":{"body":"\u003cp\u003eHello,\u003c/p\u003e\n\u003cp\u003eThank you for joining us at {APP_NAME}.\u003c/p\u003e\n\u003cp\u003eClick on the button below to verify your email address.\u003c/p\u003e\n\u003cp\u003e\n \u003ca class=\"btn\" href=\"{ACTION_URL}\" target=\"_blank\" rel=\"noopener\"\u003eVerify\u003c/a\u003e\n\u003c/p\u003e\n\u003cp\u003e\n Thanks,\u003cbr/\u003e\n {APP_NAME} team\n\u003c/p\u003e","subject":"Verify your {APP_NAME} email","actionUrl":"{APP_URL}/_/#/auth/confirm-verification/{TOKEN}"},"resetPasswordTemplate":{"body":"\u003cp\u003eHello,\u003c/p\u003e\n\u003cp\u003eClick on the button below to reset your password.\u003c/p\u003e\n\u003cp\u003e\n \u003ca class=\"btn\" href=\"{ACTION_URL}\" target=\"_blank\" rel=\"noopener\"\u003eReset password\u003c/a\u003e\n\u003c/p\u003e\n\u003cp\u003e\u003ci\u003eIf you didn't ask to reset your password, you can ignore this email.\u003c/i\u003e\u003c/p\u003e\n\u003cp\u003e\n Thanks,\u003cbr/\u003e\n {APP_NAME} team\n\u003c/p\u003e","subject":"Reset your {APP_NAME} password","actionUrl":"{APP_URL}/_/#/auth/confirm-password-reset/{TOKEN}"},"confirmEmailChangeTemplate":{"body":"\u003cp\u003eHello,\u003c/p\u003e\n\u003cp\u003eClick on the button below to confirm your new email address.\u003c/p\u003e\n\u003cp\u003e\n \u003ca class=\"btn\" href=\"{ACTION_URL}\" target=\"_blank\" rel=\"noopener\"\u003eConfirm new email\u003c/a\u003e\n\u003c/p\u003e\n\u003cp\u003e\u003ci\u003eIf you didn't ask to change your email address, you can ignore this email.\u003c/i\u003e\u003c/p\u003e\n\u003cp\u003e\n Thanks,\u003cbr/\u003e\n {APP_NAME} team\n\u003c/p\u003e","subject":"Confirm your {APP_NAME} new email address","actionUrl":"{APP_URL}/_/#/auth/confirm-email-change/{TOKEN}"}},"logs":{"maxDays":5},"smtp":{"enabled":false,"host":"smtp.example.com","port":587,"username":"","password":"******","tls":true},"s3":{"enabled":false,"bucket":"","region":"","endpoint":"","accessKey":"","secret":"******","forcePathStyle":false},"adminAuthToken":{"secret":"******","duration":1209600},"adminPasswordResetToken":{"secret":"******","duration":1800},"recordAuthToken":{"secret":"******","duration":1209600},"recordPasswordResetToken":{"secret":"******","duration":1800},"recordEmailChangeToken":{"secret":"******","duration":1800},"recordVerificationToken":{"secret":"******","duration":604800},"emailAuth":{"enabled":false,"exceptDomains":null,"onlyDomains":null,"minPasswordLength":0},"googleAuth":{"enabled":false,"clientSecret":"******"},"facebookAuth":{"enabled":false,"clientSecret":"******"},"githubAuth":{"enabled":false,"clientSecret":"******"},"gitlabAuth":{"enabled":false,"clientSecret":"******"},"discordAuth":{"enabled":false,"clientSecret":"******"},"twitterAuth":{"enabled":false,"clientSecret":"******"}}`
if encodedStr := string(encoded); encodedStr != expected {
t.Fatalf("Expected %v, got \n%v", expected, encodedStr)
t.Fatalf("Expected\n%v\ngot\n%v", expected, encodedStr)
}
}
@@ -210,10 +206,10 @@ func TestNamedAuthProviderConfigs(t *testing.T) {
t.Fatal(err)
}
expected := `{"discord":{"enabled":false,"allowRegistrations":true,"clientId":"discord_test"},"facebook":{"enabled":false,"allowRegistrations":true,"clientId":"facebook_test"},"github":{"enabled":false,"allowRegistrations":true,"clientId":"github_test"},"gitlab":{"enabled":true,"allowRegistrations":true,"clientId":"gitlab_test"},"google":{"enabled":false,"allowRegistrations":true,"clientId":"google_test"},"twitter":{"enabled":false,"allowRegistrations":true,"clientId":"twitter_test"}}`
expected := `{"discord":{"enabled":false,"clientId":"discord_test"},"facebook":{"enabled":false,"clientId":"facebook_test"},"github":{"enabled":false,"clientId":"github_test"},"gitlab":{"enabled":true,"clientId":"gitlab_test"},"google":{"enabled":false,"clientId":"google_test"},"twitter":{"enabled":false,"clientId":"twitter_test"}}`
if encodedStr := string(encoded); encodedStr != expected {
t.Fatalf("Expected the same serialization, got %v", encodedStr)
t.Fatalf("Expected the same serialization, got \n%v", encodedStr)
}
}
@@ -701,83 +697,24 @@ func TestAuthProviderConfigSetupProvider(t *testing.T) {
if err := c2.SetupProvider(provider); err != nil {
t.Error(err)
}
encoded, _ := json.Marshal(c2)
expected := `{"enabled":true,"allowRegistrations":false,"clientId":"test_ClientId","clientSecret":"test_ClientSecret","authUrl":"test_AuthUrl","tokenUrl":"test_TokenUrl","userApiUrl":"test_UserApiUrl"}`
if string(encoded) != expected {
t.Errorf("Expected %s, got %s", expected, string(encoded))
}
}
func TestEmailAuthConfigValidate(t *testing.T) {
scenarios := []struct {
config core.EmailAuthConfig
expectError bool
}{
// zero values (disabled)
{
core.EmailAuthConfig{},
false,
},
// zero values (enabled)
{
core.EmailAuthConfig{Enabled: true},
true,
},
// invalid data (only the required)
{
core.EmailAuthConfig{
Enabled: true,
MinPasswordLength: 4,
},
true,
},
// valid data (only the required)
{
core.EmailAuthConfig{
Enabled: true,
MinPasswordLength: 5,
},
false,
},
// invalid data (both OnlyDomains and ExceptDomains set)
{
core.EmailAuthConfig{
Enabled: true,
MinPasswordLength: 5,
OnlyDomains: []string{"example.com", "test.com"},
ExceptDomains: []string{"example.com", "test.com"},
},
true,
},
// valid data (only onlyDomains set)
{
core.EmailAuthConfig{
Enabled: true,
MinPasswordLength: 5,
OnlyDomains: []string{"example.com", "test.com"},
},
false,
},
// valid data (only exceptDomains set)
{
core.EmailAuthConfig{
Enabled: true,
MinPasswordLength: 5,
ExceptDomains: []string{"example.com", "test.com"},
},
false,
},
}
for i, scenario := range scenarios {
result := scenario.config.Validate()
if result != nil && !scenario.expectError {
t.Errorf("(%d) Didn't expect error, got %v", i, result)
}
if result == nil && scenario.expectError {
t.Errorf("(%d) Expected error, got nil", i)
}
if provider.ClientId() != c2.ClientId {
t.Fatalf("Expected ClientId %s, got %s", c2.ClientId, provider.ClientId())
}
if provider.ClientSecret() != c2.ClientSecret {
t.Fatalf("Expected ClientSecret %s, got %s", c2.ClientSecret, provider.ClientSecret())
}
if provider.AuthUrl() != c2.AuthUrl {
t.Fatalf("Expected AuthUrl %s, got %s", c2.AuthUrl, provider.AuthUrl())
}
if provider.UserApiUrl() != c2.UserApiUrl {
t.Fatalf("Expected UserApiUrl %s, got %s", c2.UserApiUrl, provider.UserApiUrl())
}
if provider.TokenUrl() != c2.TokenUrl {
t.Fatalf("Expected TokenUrl %s, got %s", c2.TokenUrl, provider.TokenUrl())
}
}