Skip to content

Commit

Permalink
add filter:api.user.signup.requires-approval.result
Browse files Browse the repository at this point in the history
closes #6691
  • Loading branch information
kontrollanten committed Jan 24, 2025
1 parent d16d2e6 commit f8259c5
Show file tree
Hide file tree
Showing 15 changed files with 225 additions and 57 deletions.
18 changes: 12 additions & 6 deletions client/src/app/+signup/+register/register.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { AuthService, ServerService } from '@app/core'
import { HooksService } from '@app/core/plugins/hooks.service'
import { InstanceAboutAccordionComponent } from '@app/shared/shared-instance/instance-about-accordion.component'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { PeerTubeProblemDocument, ServerConfig, ServerStats, UserRegister } from '@peertube/peertube-models'
import { UserRegistrationState, PeerTubeProblemDocument, ServerConfig, ServerStats, UserRegister } from '@peertube/peertube-models'
import { LoaderComponent } from '../../shared/shared-main/common/loader.component'
import { SignupLabelComponent } from '../../shared/shared-main/users/signup-label.component'
import { SignupStepTitleComponent } from '../shared/signup-step-title.component'
Expand Down Expand Up @@ -78,6 +78,7 @@ export class RegisterComponent implements OnInit {
serverStats: ServerStats

private serverConfig: ServerConfig
private _requiresApproval: boolean

constructor (
private route: ActivatedRoute,
Expand All @@ -92,7 +93,11 @@ export class RegisterComponent implements OnInit {
}

get requiresApproval () {
return this.serverConfig.signup.requiresApproval
return this._requiresApproval ?? this.serverConfig.signup.requiresApproval
}

set requiresApproval (value: boolean) {
this._requiresApproval = value
}

get minimumAge () {
Expand Down Expand Up @@ -197,12 +202,13 @@ export class RegisterComponent implements OnInit {
'filter:api.signup.registration.create.params'
)

const obs = this.requiresApproval
? this.signupService.requestSignup(body)
: this.signupService.directSignup(body)
const obs = this.signupService.signup(body)

obs.subscribe({
next: () => {
next: (registration) => {
const { state } = registration
this.requiresApproval = state.id === UserRegistrationState.PENDING

if (this.requiresEmailVerification || this.requiresApproval) {
this.signupSuccess = true
return
Expand Down
11 changes: 3 additions & 8 deletions client/src/app/+signup/shared/signup.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ 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 '@peertube/peertube-models'
import { UserRegister, UserRegistration as UserRegistrationServerModel } from '@peertube/peertube-models'

@Injectable()
export class SignupService {
Expand All @@ -13,19 +13,14 @@ export class SignupService {
private userService: UserService
) { }

directSignup (userCreate: UserRegister) {
return this.authHttp.post(UserService.BASE_USERS_URL + 'register', userCreate)
signup (userCreate: UserRegister) {
return this.authHttp.post<UserRegistrationServerModel>(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: {
Expand Down
3 changes: 3 additions & 0 deletions packages/models/src/plugins/server/server-hook.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ export const serverFilterHookObject = {
// Filter result used to check if a user can register on the instance
'filter:api.user.signup.allowed.result': true,

// Filter result used to check if signup requires approval on the instance
'filter:api.user.signup.requires-approval.result': true,

// Filter result used to check if a user can send a registration request on the instance
// PeerTube >= 5.1
'filter:api.user.request-signup.allowed.result': true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { UserRegistrationStateType } from './user-registration-state.model.js'

export interface UserRegistrationResponse {
state: {
id: UserRegistrationStateType
label: string
}
}

export interface UserRegistration {
id: number

Expand Down
4 changes: 2 additions & 2 deletions packages/server-commands/src/users/registrations-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ export class RegistrationsCommand extends AbstractCommand {

path,
fields: {
...pick(options, [ 'username', 'displayName', 'channel' ]),
...pick(options, [ 'username', 'displayName', 'channel', 'registrationReason' ]),

password,
email
},
implicitToken: false,
defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
defaultExpectedStatus: HttpStatusCode.OK_200
})
}

Expand Down
10 changes: 10 additions & 0 deletions packages/tests/fixtures/peertube-plugin-test/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,16 @@ async function register ({ registerHook, registerSetting, settingsManager, stora
}
})

registerHook({
target: 'filter:api.user.signup.requires-approval.result',
handler: ({ requiresApproval, registrationReason }, { body, headers }) => {
return {
requiresApproval: body.username === 'waiting_john',
registrationReason: 'Marked as spam'
}
}
})

{
registerHook({
target: 'filter:api.user.signup.allowed.result',
Expand Down
33 changes: 22 additions & 11 deletions packages/tests/src/api/check-params/registrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,10 @@ describe('Test registrations API validators', function () {
const { total } = await server.users.list()

await server.config.enableSignup(false, total + 1)
await server.registrations.register({ username: 'user43', expectedStatus: HttpStatusCode.NO_CONTENT_204 })
await server.registrations.register({ username: 'user43', expectedStatus: HttpStatusCode.OK_200 })

await server.config.enableSignup(true, total + 2)
await server.registrations.requestRegistration({
await server.registrations.register({
username: 'user44',
registrationReason: 'reason',
expectedStatus: HttpStatusCode.OK_200
Expand All @@ -214,14 +214,14 @@ describe('Test registrations API validators', function () {
channel: { name: 'super_user_direct_1_channel', displayName: 'super user direct 1 channel' }
}

await makePostBodyRequest({ url: server.url, path: registrationPath, fields, expectedStatus: HttpStatusCode.NO_CONTENT_204 })
await makePostBodyRequest({ url: server.url, path: registrationPath, fields, expectedStatus: HttpStatusCode.OK_200 })
})

it('Should fail if the instance requires approval', async function () {
it('Should fail if registration reason isnt provided', async function () {
this.timeout(60000)

await server.config.enableSignup(true)
await server.registrations.register({ username: 'user42', expectedStatus: HttpStatusCode.FORBIDDEN_403 })
await server.registrations.register({ username: 'user42', expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
})
})

Expand Down Expand Up @@ -312,10 +312,15 @@ describe('Test registrations API validators', function () {
before(async function () {
this.timeout(60000)

await server.config.enableSignup(true);
await server.config.enableSignup(true)

await server.registrations.requestRegistration({ username: 'request_2', registrationReason: 'toto' })
await server.registrations.requestRegistration({ username: 'request_3', registrationReason: 'toto' })

({ id: id1 } = await server.registrations.requestRegistration({ username: 'request_2', registrationReason: 'toto' }));
({ id: id2 } = await server.registrations.requestRegistration({ username: 'request_3', registrationReason: 'toto' }))
const registrations = await server.registrations.list()

id1 = registrations.data[0].id
id2 = registrations.data[1].id
})

it('Should fail to accept/reject registration without token', async function () {
Expand Down Expand Up @@ -375,9 +380,15 @@ describe('Test registrations API validators', function () {
let id3: number

before(async function () {
({ id: id1 } = await server.registrations.requestRegistration({ username: 'request_4', registrationReason: 'toto' }));
({ id: id2 } = await server.registrations.requestRegistration({ username: 'request_5', registrationReason: 'toto' }));
({ id: id3 } = await server.registrations.requestRegistration({ username: 'request_6', registrationReason: 'toto' }))
await server.registrations.requestRegistration({ username: 'request_4', registrationReason: 'toto' })
await server.registrations.requestRegistration({ username: 'request_5', registrationReason: 'toto' })
await server.registrations.requestRegistration({ username: 'request_6', registrationReason: 'toto' })

const registrations = await server.registrations.list()

id1 = registrations.data[0].id
id2 = registrations.data[1].id
id3 = registrations.data[2].id

await server.registrations.accept({ id: id2, moderationResponse: 'tt' })
await server.registrations.reject({ id: id3, moderationResponse: 'tt' })
Expand Down
5 changes: 3 additions & 2 deletions packages/tests/src/api/server/email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,12 +314,13 @@ describe('Test emails', function () {
let registrationIdEmail: number

before(async function () {
const { id } = await server.registrations.requestRegistration({
await server.registrations.requestRegistration({
username: 'request_1',
email: '[email protected]',
registrationReason: 'tt'
})
registrationId = id
const registrations = await server.registrations.list()
registrationId = registrations.data[0].id
})

it('Should ask to send the verification email', async function () {
Expand Down
2 changes: 1 addition & 1 deletion packages/tests/src/api/server/reverse-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ describe('Test application behind a reverse proxy', function () {
await server.registrations.register({ username: 'test' + i, expectedStatus: HttpStatusCode.CONFLICT_409 })
}

await server.registrations.register({ username: 'test43', expectedStatus: HttpStatusCode.NO_CONTENT_204 })
await server.registrations.register({ username: 'test43', expectedStatus: HttpStatusCode.OK_200 })

})

Expand Down
9 changes: 6 additions & 3 deletions packages/tests/src/api/server/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,9 +316,12 @@ describe('Test stats (excluding redundancy)', function () {
it('Should create registration requests, accept one and have correct stats', async function () {
beforeTimestamp = new Date().getTime()

const { id: id1 } = await servers[0].registrations.requestRegistration({ username: 'user2', registrationReason: 'reason 1' });
({ id: id2 } = await servers[0].registrations.requestRegistration({ username: 'user3', registrationReason: 'reason 2' }))
await servers[0].registrations.requestRegistration({ username: 'user4', registrationReason: 'reason 3' })
await servers[0].registrations.register({ username: 'user2', registrationReason: 'reason 1' })
await servers[0].registrations.register({ username: 'user3', registrationReason: 'reason 2' })
const registrations = await servers[0].registrations.list()
const id1 = registrations.data[1].id
id2 = registrations.data[0].id
await servers[0].registrations.register({ username: 'user4', registrationReason: 'reason 3' })

await wait(1500)

Expand Down
Loading

0 comments on commit f8259c5

Please sign in to comment.