From 9589907c89d29a6c0acd52c8cb789af9f93ce9af Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 19 Jan 2023 09:29:47 +0100 Subject: Implement signup approval in client --- .../app/+signup/+register/register.component.html | 35 +++++---- .../app/+signup/+register/register.component.ts | 62 +++++++++++----- client/src/app/+signup/+register/shared/index.ts | 1 + .../+register/shared/register-validators.ts | 18 +++++ .../steps/register-step-about.component.html | 4 + .../steps/register-step-about.component.ts | 1 + .../steps/register-step-channel.component.ts | 6 +- .../steps/register-step-terms.component.html | 14 +++- .../steps/register-step-terms.component.ts | 10 ++- .../steps/register-step-user.component.ts | 6 +- .../verify-account-ask-send-email.component.ts | 6 +- .../verify-account-email.component.html | 17 +++-- .../verify-account-email.component.ts | 86 ++++++++++++++++++++-- .../src/app/+signup/shared/shared-signup.module.ts | 11 ++- .../signup-success-after-email.component.html | 21 ++++++ .../shared/signup-success-after-email.component.ts | 10 +++ .../signup-success-before-email.component.html | 35 +++++++++ .../signup-success-before-email.component.ts | 12 +++ .../+signup/shared/signup-success.component.html | 22 ------ .../app/+signup/shared/signup-success.component.ts | 19 ----- client/src/app/+signup/shared/signup.service.ts | 85 +++++++++++++++++++++ 21 files changed, 379 insertions(+), 102 deletions(-) create mode 100644 client/src/app/+signup/+register/shared/index.ts create mode 100644 client/src/app/+signup/+register/shared/register-validators.ts create mode 100644 client/src/app/+signup/shared/signup-success-after-email.component.html create mode 100644 client/src/app/+signup/shared/signup-success-after-email.component.ts create mode 100644 client/src/app/+signup/shared/signup-success-before-email.component.html create mode 100644 client/src/app/+signup/shared/signup-success-before-email.component.ts delete mode 100644 client/src/app/+signup/shared/signup-success.component.html delete mode 100644 client/src/app/+signup/shared/signup-success.component.ts create mode 100644 client/src/app/+signup/shared/signup.service.ts (limited to 'client/src/app/+signup') diff --git a/client/src/app/+signup/+register/register.component.html b/client/src/app/+signup/+register/register.component.html index bafb96a49..86763e801 100644 --- a/client/src/app/+signup/+register/register.component.html +++ b/client/src/app/+signup/+register/register.component.html @@ -5,29 +5,34 @@ -

+

{{ instanceName }} > - Create an account +

- - Create an account -
on {{ instanceName }}
+ + + + + +
on {{ instanceName }}
- +
I already have an account, I log in - +
@@ -44,8 +49,8 @@ > @@ -94,14 +99,15 @@
You will be able to create a channel later
- -
+ +
PeerTube is creating your account...
@@ -109,7 +115,10 @@
{{ signupError }}
- +
diff --git a/client/src/app/+signup/+register/register.component.ts b/client/src/app/+signup/+register/register.component.ts index 958770ebf..9259d902c 100644 --- a/client/src/app/+signup/+register/register.component.ts +++ b/client/src/app/+signup/+register/register.component.ts @@ -5,10 +5,10 @@ import { ActivatedRoute } from '@angular/router' import { AuthService } from '@app/core' import { HooksService } from '@app/core/plugins/hooks.service' import { InstanceAboutAccordionComponent } from '@app/shared/shared-instance' -import { UserSignupService } from '@app/shared/shared-users' import { NgbAccordion } from '@ng-bootstrap/ng-bootstrap' import { UserRegister } from '@shared/models' import { ServerConfig } from '@shared/models/server' +import { SignupService } from '../shared/signup.service' @Component({ selector: 'my-register', @@ -53,7 +53,7 @@ export class RegisterComponent implements OnInit { constructor ( private route: ActivatedRoute, private authService: AuthService, - private userSignupService: UserSignupService, + private signupService: SignupService, private hooks: HooksService ) { } @@ -61,6 +61,10 @@ export class RegisterComponent implements OnInit { return this.serverConfig.signup.requiresEmailVerification } + get requiresApproval () { + return this.serverConfig.signup.requiresApproval + } + get minimumAge () { return this.serverConfig.signup.minimumAge } @@ -132,42 +136,49 @@ export class RegisterComponent implements OnInit { skipChannelCreation () { this.formStepChannel.reset() this.lastStep.select() + this.signup() } async signup () { this.signupError = undefined - const body: UserRegister = await this.hooks.wrapObject( + const termsForm = this.formStepTerms.value + const userForm = this.formStepUser.value + const channelForm = this.formStepChannel?.value + + const channel = this.formStepChannel?.value?.name + ? { name: channelForm?.name, displayName: channelForm?.displayName } + : undefined + + const body = await this.hooks.wrapObject( { - ...this.formStepUser.value, + username: userForm.username, + password: userForm.password, + email: userForm.email, + displayName: userForm.displayName, + + registrationReason: termsForm.registrationReason, - channel: this.formStepChannel?.value?.name - ? this.formStepChannel.value - : undefined + channel }, 'signup', 'filter:api.signup.registration.create.params' ) - this.userSignupService.signup(body).subscribe({ + const obs = this.requiresApproval + ? this.signupService.requestSignup(body) + : this.signupService.directSignup(body) + + obs.subscribe({ next: () => { - if (this.requiresEmailVerification) { + if (this.requiresEmailVerification || this.requiresApproval) { this.signupSuccess = true return } // Auto login - this.authService.login({ username: body.username, password: body.password }) - .subscribe({ - next: () => { - this.signupSuccess = true - }, - - error: err => { - this.signupError = err.message - } - }) + this.autoLogin(body) }, error: err => { @@ -175,4 +186,17 @@ export class RegisterComponent implements OnInit { } }) } + + private autoLogin (body: UserRegister) { + this.authService.login({ username: body.username, password: body.password }) + .subscribe({ + next: () => { + this.signupSuccess = true + }, + + error: err => { + this.signupError = err.message + } + }) + } } diff --git a/client/src/app/+signup/+register/shared/index.ts b/client/src/app/+signup/+register/shared/index.ts new file mode 100644 index 000000000..affb54bf4 --- /dev/null +++ b/client/src/app/+signup/+register/shared/index.ts @@ -0,0 +1 @@ +export * from './register-validators' diff --git a/client/src/app/+signup/+register/shared/register-validators.ts b/client/src/app/+signup/+register/shared/register-validators.ts new file mode 100644 index 000000000..f14803b68 --- /dev/null +++ b/client/src/app/+signup/+register/shared/register-validators.ts @@ -0,0 +1,18 @@ +import { Validators } from '@angular/forms' +import { BuildFormValidator } from '@app/shared/form-validators' + +export const REGISTER_TERMS_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.requiredTrue ], + MESSAGES: { + required: $localize`You must agree with the instance terms in order to register on it.` + } +} + +export const REGISTER_REASON_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ], + MESSAGES: { + required: $localize`Registration reason is required.`, + minlength: $localize`Registration reason must be at least 2 characters long.`, + maxlength: $localize`Registration reason cannot be more than 3000 characters long.` + } +} diff --git a/client/src/app/+signup/+register/steps/register-step-about.component.html b/client/src/app/+signup/+register/steps/register-step-about.component.html index 769fe3127..580e8a92c 100644 --- a/client/src/app/+signup/+register/steps/register-step-about.component.html +++ b/client/src/app/+signup/+register/steps/register-step-about.component.html @@ -13,6 +13,10 @@
  • Have access to your watch history
  • Create your channel to publish videos
  • + +

    + Moderators of {{ instanceName }} will have to approve your registration request once you have finished to fill the form. +

    diff --git a/client/src/app/+signup/+register/steps/register-step-about.component.ts b/client/src/app/+signup/+register/steps/register-step-about.component.ts index 9a0941016..b176ffa59 100644 --- a/client/src/app/+signup/+register/steps/register-step-about.component.ts +++ b/client/src/app/+signup/+register/steps/register-step-about.component.ts @@ -7,6 +7,7 @@ import { ServerService } from '@app/core' styleUrls: [ './register-step-about.component.scss' ] }) export class RegisterStepAboutComponent { + @Input() requiresApproval: boolean @Input() videoUploadDisabled: boolean constructor (private serverService: ServerService) { diff --git a/client/src/app/+signup/+register/steps/register-step-channel.component.ts b/client/src/app/+signup/+register/steps/register-step-channel.component.ts index df92c5145..478ca0177 100644 --- a/client/src/app/+signup/+register/steps/register-step-channel.component.ts +++ b/client/src/app/+signup/+register/steps/register-step-channel.component.ts @@ -2,9 +2,9 @@ import { concat, of } from 'rxjs' import { pairwise } from 'rxjs/operators' import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core' import { FormGroup } from '@angular/forms' +import { SignupService } from '@app/+signup/shared/signup.service' import { VIDEO_CHANNEL_DISPLAY_NAME_VALIDATOR, VIDEO_CHANNEL_NAME_VALIDATOR } from '@app/shared/form-validators/video-channel-validators' import { FormReactive, FormReactiveService } from '@app/shared/shared-forms' -import { UserSignupService } from '@app/shared/shared-users' @Component({ selector: 'my-register-step-channel', @@ -20,7 +20,7 @@ export class RegisterStepChannelComponent extends FormReactive implements OnInit constructor ( protected formReactiveService: FormReactiveService, - private userSignupService: UserSignupService + private signupService: SignupService ) { super() } @@ -51,7 +51,7 @@ export class RegisterStepChannelComponent extends FormReactive implements OnInit private onDisplayNameChange (oldDisplayName: string, newDisplayName: string) { const name = this.form.value['name'] || '' - const newName = this.userSignupService.getNewUsername(oldDisplayName, newDisplayName, name) + const newName = this.signupService.getNewUsername(oldDisplayName, newDisplayName, name) this.form.patchValue({ name: newName }) } } diff --git a/client/src/app/+signup/+register/steps/register-step-terms.component.html b/client/src/app/+signup/+register/steps/register-step-terms.component.html index cbfb32518..1d753a3f2 100644 --- a/client/src/app/+signup/+register/steps/register-step-terms.component.html +++ b/client/src/app/+signup/+register/steps/register-step-terms.component.html @@ -1,4 +1,16 @@
    + +
    + + + + +
    {{ formErrors.registrationReason }}
    +
    +
    @@ -6,7 +18,7 @@ I am at least {{ minimumAge }} years old and agree to the Terms and to the Code of Conduct - of this instance + of {{ instanceName }} diff --git a/client/src/app/+signup/+register/steps/register-step-terms.component.ts b/client/src/app/+signup/+register/steps/register-step-terms.component.ts index 2df963b30..1b1fb49ee 100644 --- a/client/src/app/+signup/+register/steps/register-step-terms.component.ts +++ b/client/src/app/+signup/+register/steps/register-step-terms.component.ts @@ -1,7 +1,7 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core' import { FormGroup } from '@angular/forms' -import { USER_TERMS_VALIDATOR } from '@app/shared/form-validators/user-validators' import { FormReactive, FormReactiveService } from '@app/shared/shared-forms' +import { REGISTER_REASON_VALIDATOR, REGISTER_TERMS_VALIDATOR } from '../shared' @Component({ selector: 'my-register-step-terms', @@ -10,7 +10,9 @@ import { FormReactive, FormReactiveService } from '@app/shared/shared-forms' }) export class RegisterStepTermsComponent extends FormReactive implements OnInit { @Input() hasCodeOfConduct = false + @Input() requiresApproval: boolean @Input() minimumAge = 16 + @Input() instanceName: string @Output() formBuilt = new EventEmitter() @Output() termsClick = new EventEmitter() @@ -28,7 +30,11 @@ export class RegisterStepTermsComponent extends FormReactive implements OnInit { ngOnInit () { this.buildForm({ - terms: USER_TERMS_VALIDATOR + terms: REGISTER_TERMS_VALIDATOR, + + registrationReason: this.requiresApproval + ? REGISTER_REASON_VALIDATOR + : null }) setTimeout(() => this.formBuilt.emit(this.form)) diff --git a/client/src/app/+signup/+register/steps/register-step-user.component.ts b/client/src/app/+signup/+register/steps/register-step-user.component.ts index 822f8f5c5..0a5d2e437 100644 --- a/client/src/app/+signup/+register/steps/register-step-user.component.ts +++ b/client/src/app/+signup/+register/steps/register-step-user.component.ts @@ -2,6 +2,7 @@ import { concat, of } from 'rxjs' import { pairwise } from 'rxjs/operators' import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core' import { FormGroup } from '@angular/forms' +import { SignupService } from '@app/+signup/shared/signup.service' import { USER_DISPLAY_NAME_REQUIRED_VALIDATOR, USER_EMAIL_VALIDATOR, @@ -9,7 +10,6 @@ import { USER_USERNAME_VALIDATOR } from '@app/shared/form-validators/user-validators' import { FormReactive, FormReactiveService } from '@app/shared/shared-forms' -import { UserSignupService } from '@app/shared/shared-users' @Component({ selector: 'my-register-step-user', @@ -24,7 +24,7 @@ export class RegisterStepUserComponent extends FormReactive implements OnInit { constructor ( protected formReactiveService: FormReactiveService, - private userSignupService: UserSignupService + private signupService: SignupService ) { super() } @@ -57,7 +57,7 @@ export class RegisterStepUserComponent extends FormReactive implements OnInit { private onDisplayNameChange (oldDisplayName: string, newDisplayName: string) { const username = this.form.value['username'] || '' - const newUsername = this.userSignupService.getNewUsername(oldDisplayName, newDisplayName, username) + const newUsername = this.signupService.getNewUsername(oldDisplayName, newDisplayName, username) this.form.patchValue({ username: newUsername }) } } diff --git a/client/src/app/+signup/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.ts b/client/src/app/+signup/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.ts index 06905f678..75b599e0e 100644 --- a/client/src/app/+signup/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.ts +++ b/client/src/app/+signup/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.ts @@ -1,8 +1,8 @@ import { Component, OnInit } from '@angular/core' +import { SignupService } from '@app/+signup/shared/signup.service' import { Notifier, RedirectService, ServerService } from '@app/core' import { USER_EMAIL_VALIDATOR } from '@app/shared/form-validators/user-validators' import { FormReactive, FormReactiveService } from '@app/shared/shared-forms' -import { UserSignupService } from '@app/shared/shared-users' @Component({ selector: 'my-verify-account-ask-send-email', @@ -15,7 +15,7 @@ export class VerifyAccountAskSendEmailComponent extends FormReactive implements constructor ( protected formReactiveService: FormReactiveService, - private userSignupService: UserSignupService, + private signupService: SignupService, private serverService: ServerService, private notifier: Notifier, private redirectService: RedirectService @@ -34,7 +34,7 @@ export class VerifyAccountAskSendEmailComponent extends FormReactive implements askSendVerifyEmail () { const email = this.form.value['verify-email-email'] - this.userSignupService.askSendVerifyEmail(email) + this.signupService.askSendVerifyEmail(email) .subscribe({ next: () => { this.notifier.success($localize`An email with verification link will be sent to ${email}.`) diff --git a/client/src/app/+signup/+verify-account/verify-account-email/verify-account-email.component.html b/client/src/app/+signup/+verify-account/verify-account-email/verify-account-email.component.html index 122f3c28c..8c8b1098e 100644 --- a/client/src/app/+signup/+verify-account/verify-account-email/verify-account-email.component.html +++ b/client/src/app/+signup/+verify-account/verify-account-email/verify-account-email.component.html @@ -1,14 +1,19 @@ -
    -

    Verify account email confirmation

    +
    +

    Verify email

    - - + + -
    Email updated.
    +
    Email updated.
    diff --git a/client/src/app/+signup/+verify-account/verify-account-email/verify-account-email.component.ts b/client/src/app/+signup/+verify-account/verify-account-email/verify-account-email.component.ts index 88efce4a1..faf663391 100644 --- a/client/src/app/+signup/+verify-account/verify-account-email/verify-account-email.component.ts +++ b/client/src/app/+signup/+verify-account/verify-account-email/verify-account-email.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit } from '@angular/core' import { ActivatedRoute } from '@angular/router' -import { AuthService, Notifier } from '@app/core' -import { UserSignupService } from '@app/shared/shared-users' +import { SignupService } from '@app/+signup/shared/signup.service' +import { AuthService, Notifier, ServerService } from '@app/core' @Component({ selector: 'my-verify-account-email', @@ -13,32 +13,82 @@ export class VerifyAccountEmailComponent implements OnInit { failed = false isPendingEmail = false + requiresApproval: boolean + loaded = false + private userId: number + private registrationId: number private verificationString: string constructor ( - private userSignupService: UserSignupService, + private signupService: SignupService, + private server: ServerService, private authService: AuthService, private notifier: Notifier, private route: ActivatedRoute ) { } + get instanceName () { + return this.server.getHTMLConfig().instance.name + } + ngOnInit () { const queryParams = this.route.snapshot.queryParams + + this.server.getConfig().subscribe(config => { + this.requiresApproval = config.signup.requiresApproval + + this.loaded = true + }) + this.userId = queryParams['userId'] + this.registrationId = queryParams['registrationId'] + this.verificationString = queryParams['verificationString'] + this.isPendingEmail = queryParams['isPendingEmail'] === 'true' - if (!this.userId || !this.verificationString) { - this.notifier.error($localize`Unable to find user id or verification string.`) - } else { - this.verifyEmail() + if (!this.verificationString) { + this.notifier.error($localize`Unable to find verification string in URL query.`) + return + } + + if (!this.userId && !this.registrationId) { + this.notifier.error($localize`Unable to find user id or registration id in URL query.`) + return } + + this.verifyEmail() + } + + isRegistrationRequest () { + return !!this.registrationId + } + + displaySignupSuccess () { + if (!this.success) return false + if (!this.isRegistrationRequest() && this.isPendingEmail) return false + + return true } verifyEmail () { - this.userSignupService.verifyEmail(this.userId, this.verificationString, this.isPendingEmail) + if (this.isRegistrationRequest()) { + return this.verifyRegistrationEmail() + } + + return this.verifyUserEmail() + } + + private verifyUserEmail () { + const options = { + userId: this.userId, + verificationString: this.verificationString, + isPendingEmail: this.isPendingEmail + } + + this.signupService.verifyUserEmail(options) .subscribe({ next: () => { if (this.authService.isLoggedIn()) { @@ -55,4 +105,24 @@ export class VerifyAccountEmailComponent implements OnInit { } }) } + + private verifyRegistrationEmail () { + const options = { + registrationId: this.registrationId, + verificationString: this.verificationString + } + + this.signupService.verifyRegistrationEmail(options) + .subscribe({ + next: () => { + this.success = true + }, + + error: err => { + this.failed = true + + this.notifier.error(err.message) + } + }) + } } diff --git a/client/src/app/+signup/shared/shared-signup.module.ts b/client/src/app/+signup/shared/shared-signup.module.ts index 0aa08f3e2..0600f0af8 100644 --- a/client/src/app/+signup/shared/shared-signup.module.ts +++ b/client/src/app/+signup/shared/shared-signup.module.ts @@ -5,7 +5,9 @@ import { SharedMainModule } from '@app/shared/shared-main' import { SharedUsersModule } from '@app/shared/shared-users' import { SignupMascotComponent } from './signup-mascot.component' import { SignupStepTitleComponent } from './signup-step-title.component' -import { SignupSuccessComponent } from './signup-success.component' +import { SignupSuccessBeforeEmailComponent } from './signup-success-before-email.component' +import { SignupSuccessAfterEmailComponent } from './signup-success-after-email.component' +import { SignupService } from './signup.service' @NgModule({ imports: [ @@ -16,7 +18,8 @@ import { SignupSuccessComponent } from './signup-success.component' ], declarations: [ - SignupSuccessComponent, + SignupSuccessBeforeEmailComponent, + SignupSuccessAfterEmailComponent, SignupStepTitleComponent, SignupMascotComponent ], @@ -26,12 +29,14 @@ import { SignupSuccessComponent } from './signup-success.component' SharedFormModule, SharedGlobalIconModule, - SignupSuccessComponent, + SignupSuccessBeforeEmailComponent, + SignupSuccessAfterEmailComponent, SignupStepTitleComponent, SignupMascotComponent ], providers: [ + SignupService ] }) export class SharedSignupModule { } diff --git a/client/src/app/+signup/shared/signup-success-after-email.component.html b/client/src/app/+signup/shared/signup-success-after-email.component.html new file mode 100644 index 000000000..1c3536ada --- /dev/null +++ b/client/src/app/+signup/shared/signup-success-after-email.component.html @@ -0,0 +1,21 @@ + + Email verified! + + +
    + +

    Your email has been verified and your account request has been sent!

    + +

    + A moderator will check your registration request soon and you'll receive an email when it will be accepted or rejected. +

    +
    + + +

    Your email has been verified and your account has been created!

    + +

    + If you need help to use PeerTube, you can have a look at the documentation. +

    +
    +
    diff --git a/client/src/app/+signup/shared/signup-success-after-email.component.ts b/client/src/app/+signup/shared/signup-success-after-email.component.ts new file mode 100644 index 000000000..3d72fdae9 --- /dev/null +++ b/client/src/app/+signup/shared/signup-success-after-email.component.ts @@ -0,0 +1,10 @@ +import { Component, Input } from '@angular/core' + +@Component({ + selector: 'my-signup-success-after-email', + templateUrl: './signup-success-after-email.component.html', + styleUrls: [ './signup-success.component.scss' ] +}) +export class SignupSuccessAfterEmailComponent { + @Input() requiresApproval: boolean +} diff --git a/client/src/app/+signup/shared/signup-success-before-email.component.html b/client/src/app/+signup/shared/signup-success-before-email.component.html new file mode 100644 index 000000000..b9668ee82 --- /dev/null +++ b/client/src/app/+signup/shared/signup-success-before-email.component.html @@ -0,0 +1,35 @@ + + + Account request sent + + + + Welcome +
    on {{ instanceName }}
    +
    +
    + +
    +

    Your account request has been sent!

    +

    Your account has been created!

    + + +

    + Check your emails to validate your account and complete your registration request. +

    + +

    + Check your emails to validate your account and complete your registration. +

    +
    + + +

    + A moderator will check your registration request soon and you'll receive an email when it will be accepted or rejected. +

    + +

    + If you need help to use PeerTube, you can have a look at the documentation. +

    +
    +
    diff --git a/client/src/app/+signup/shared/signup-success-before-email.component.ts b/client/src/app/+signup/shared/signup-success-before-email.component.ts new file mode 100644 index 000000000..d72462340 --- /dev/null +++ b/client/src/app/+signup/shared/signup-success-before-email.component.ts @@ -0,0 +1,12 @@ +import { Component, Input } from '@angular/core' + +@Component({ + selector: 'my-signup-success-before-email', + templateUrl: './signup-success-before-email.component.html', + styleUrls: [ './signup-success.component.scss' ] +}) +export class SignupSuccessBeforeEmailComponent { + @Input() requiresApproval: boolean + @Input() requiresEmailVerification: boolean + @Input() instanceName: string +} diff --git a/client/src/app/+signup/shared/signup-success.component.html b/client/src/app/+signup/shared/signup-success.component.html deleted file mode 100644 index c14889c72..000000000 --- a/client/src/app/+signup/shared/signup-success.component.html +++ /dev/null @@ -1,22 +0,0 @@ - - Welcome -
    on {{ instanceName }}
    -
    - -
    -

    Your account has been created!

    - -

    - Check your emails to validate your account and complete your inscription. -

    - - -

    - If you need help to use PeerTube, you can have a look at the documentation. -

    - -

    - To help moderators and other users to know who you are, don't forget to set up your account profile by adding an avatar and a description. -

    -
    -
    diff --git a/client/src/app/+signup/shared/signup-success.component.ts b/client/src/app/+signup/shared/signup-success.component.ts deleted file mode 100644 index a03f3819d..000000000 --- a/client/src/app/+signup/shared/signup-success.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Component, Input } from '@angular/core' -import { ServerService } from '@app/core' - -@Component({ - selector: 'my-signup-success', - templateUrl: './signup-success.component.html', - styleUrls: [ './signup-success.component.scss' ] -}) -export class SignupSuccessComponent { - @Input() requiresEmailVerification: boolean - - constructor (private serverService: ServerService) { - - } - - get instanceName () { - return this.serverService.getHTMLConfig().instance.name - } -} diff --git a/client/src/app/+signup/shared/signup.service.ts b/client/src/app/+signup/shared/signup.service.ts new file mode 100644 index 000000000..f647298be --- /dev/null +++ b/client/src/app/+signup/shared/signup.service.ts @@ -0,0 +1,85 @@ +import { catchError, tap } from 'rxjs/operators' +import { HttpClient } from '@angular/common/http' +import { Injectable } from '@angular/core' +import { RestExtractor, UserService } from '@app/core' +import { UserRegister, UserRegistrationRequest } from '@shared/models' + +@Injectable() +export class SignupService { + + constructor ( + private authHttp: HttpClient, + private restExtractor: RestExtractor, + private userService: UserService + ) { } + + directSignup (userCreate: UserRegister) { + return this.authHttp.post(UserService.BASE_USERS_URL + 'register', userCreate) + .pipe( + tap(() => this.userService.setSignupInThisSession(true)), + catchError(err => this.restExtractor.handleError(err)) + ) + } + + requestSignup (userCreate: UserRegistrationRequest) { + return this.authHttp.post(UserService.BASE_USERS_URL + 'registrations/request', userCreate) + .pipe(catchError(err => this.restExtractor.handleError(err))) + } + + // --------------------------------------------------------------------------- + + verifyUserEmail (options: { + userId: number + verificationString: string + isPendingEmail: boolean + }) { + const { userId, verificationString, isPendingEmail } = options + + const url = `${UserService.BASE_USERS_URL}${userId}/verify-email` + const body = { + verificationString, + isPendingEmail + } + + return this.authHttp.post(url, body) + .pipe(catchError(res => this.restExtractor.handleError(res))) + } + + verifyRegistrationEmail (options: { + registrationId: number + verificationString: string + }) { + const { registrationId, verificationString } = options + + const url = `${UserService.BASE_USERS_URL}registrations/${registrationId}/verify-email` + const body = { verificationString } + + return this.authHttp.post(url, body) + .pipe(catchError(res => this.restExtractor.handleError(res))) + } + + askSendVerifyEmail (email: string) { + const url = UserService.BASE_USERS_URL + 'ask-send-verify-email' + + return this.authHttp.post(url, { email }) + .pipe(catchError(err => this.restExtractor.handleError(err))) + } + + // --------------------------------------------------------------------------- + + getNewUsername (oldDisplayName: string, newDisplayName: string, currentUsername: string) { + // Don't update display name, the user seems to have changed it + if (this.displayNameToUsername(oldDisplayName) !== currentUsername) return currentUsername + + return this.displayNameToUsername(newDisplayName) + } + + private displayNameToUsername (displayName: string) { + if (!displayName) return '' + + return displayName + .toLowerCase() + .replace(/\s/g, '_') + .replace(/[^a-z0-9_.]/g, '') + } +} -- cgit v1.2.3