aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/shared')
-rw-r--r--client/src/app/shared/form-validators/user-validators.ts4
-rw-r--r--client/src/app/shared/shared-main/account/actor.service.ts37
-rw-r--r--client/src/app/shared/shared-main/account/index.ts1
-rw-r--r--client/src/app/shared/shared-main/index.ts3
-rw-r--r--client/src/app/shared/shared-main/router/actor-redirect-guard.service.ts46
-rw-r--r--client/src/app/shared/shared-main/router/index.ts1
-rw-r--r--client/src/app/shared/shared-main/shared-main.module.ts10
7 files changed, 59 insertions, 43 deletions
diff --git a/client/src/app/shared/form-validators/user-validators.ts b/client/src/app/shared/form-validators/user-validators.ts
index fee37e95f..976c97b87 100644
--- a/client/src/app/shared/form-validators/user-validators.ts
+++ b/client/src/app/shared/form-validators/user-validators.ts
@@ -1,12 +1,14 @@
1import { Validators } from '@angular/forms' 1import { Validators } from '@angular/forms'
2import { BuildFormValidator } from './form-validator.model' 2import { BuildFormValidator } from './form-validator.model'
3 3
4export const USER_USERNAME_REGEX_CHARACTERS = '[a-z0-9][a-z0-9._]'
5
4export const USER_USERNAME_VALIDATOR: BuildFormValidator = { 6export const USER_USERNAME_VALIDATOR: BuildFormValidator = {
5 VALIDATORS: [ 7 VALIDATORS: [
6 Validators.required, 8 Validators.required,
7 Validators.minLength(1), 9 Validators.minLength(1),
8 Validators.maxLength(50), 10 Validators.maxLength(50),
9 Validators.pattern(/^[a-z0-9][a-z0-9._]*$/) 11 Validators.pattern(new RegExp(`^${USER_USERNAME_REGEX_CHARACTERS}*$`))
10 ], 12 ],
11 MESSAGES: { 13 MESSAGES: {
12 'required': $localize`Username is required.`, 14 'required': $localize`Username is required.`,
diff --git a/client/src/app/shared/shared-main/account/actor.service.ts b/client/src/app/shared/shared-main/account/actor.service.ts
deleted file mode 100644
index 464ed4519..000000000
--- a/client/src/app/shared/shared-main/account/actor.service.ts
+++ /dev/null
@@ -1,37 +0,0 @@
1import { Observable, ReplaySubject } from 'rxjs'
2import { catchError, map, tap } from 'rxjs/operators'
3import { HttpClient } from '@angular/common/http'
4import { Injectable } from '@angular/core'
5import { RestExtractor } from '@app/core'
6import { Account as ServerAccount, VideoChannel as ServerVideoChannel } from '@shared/models'
7import { environment } from '../../../../environments/environment'
8
9type KeysOfUnion<T> = T extends T ? keyof T: never
10type ServerActor = KeysOfUnion<ServerAccount | ServerVideoChannel>
11
12@Injectable()
13export class ActorService {
14 static BASE_ACTOR_API_URL = environment.apiUrl + '/api/v1/actors/'
15
16 actorLoaded = new ReplaySubject<string>(1)
17
18 constructor (
19 private authHttp: HttpClient,
20 private restExtractor: RestExtractor
21 ) {}
22
23 getActorType (actorName: string): Observable<string> {
24 return this.authHttp.get<ServerActor>(ActorService.BASE_ACTOR_API_URL + actorName)
25 .pipe(
26 map(actorHash => {
27 if (actorHash[ 'userId' ]) {
28 return 'Account'
29 }
30
31 return 'VideoChannel'
32 }),
33 tap(actor => this.actorLoaded.next(actor)),
34 catchError(res => this.restExtractor.handleError(res))
35 )
36 }
37}
diff --git a/client/src/app/shared/shared-main/account/index.ts b/client/src/app/shared/shared-main/account/index.ts
index c6cdcd574..b80ddb9f5 100644
--- a/client/src/app/shared/shared-main/account/index.ts
+++ b/client/src/app/shared/shared-main/account/index.ts
@@ -1,4 +1,3 @@
1export * from './account.model' 1export * from './account.model'
2export * from './account.service' 2export * from './account.service'
3export * from './actor.model' 3export * from './actor.model'
4export * from './actor.service'
diff --git a/client/src/app/shared/shared-main/index.ts b/client/src/app/shared/shared-main/index.ts
index a4d813c06..3a7fd4c34 100644
--- a/client/src/app/shared/shared-main/index.ts
+++ b/client/src/app/shared/shared-main/index.ts
@@ -5,6 +5,9 @@ export * from './date'
5export * from './feeds' 5export * from './feeds'
6export * from './loaders' 6export * from './loaders'
7export * from './misc' 7export * from './misc'
8export * from './peertube-modal'
9export * from './plugins'
10export * from './router'
8export * from './users' 11export * from './users'
9export * from './video' 12export * from './video'
10export * from './video-caption' 13export * from './video-caption'
diff --git a/client/src/app/shared/shared-main/router/actor-redirect-guard.service.ts b/client/src/app/shared/shared-main/router/actor-redirect-guard.service.ts
new file mode 100644
index 000000000..49d61f945
--- /dev/null
+++ b/client/src/app/shared/shared-main/router/actor-redirect-guard.service.ts
@@ -0,0 +1,46 @@
1import { forkJoin, of } from 'rxjs'
2import { catchError, map } from 'rxjs/operators'
3import { Injectable } from '@angular/core'
4import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router'
5import { AccountService } from '../account'
6import { VideoChannelService } from '../video-channel'
7
8@Injectable()
9export class ActorRedirectGuard implements CanActivate {
10
11 constructor (
12 private router: Router,
13 private accountService: AccountService,
14 private channelService: VideoChannelService
15 ) {}
16
17 canActivate (route: ActivatedRouteSnapshot) {
18 const actorName = route.params.actorName
19
20 return forkJoin([
21 this.accountService.getAccount(actorName).pipe(this.orUndefined()),
22 this.channelService.getVideoChannel(actorName).pipe(this.orUndefined())
23 ]).pipe(
24 map(([ account, channel ]) => {
25 if (!account && !channel) {
26 this.router.navigate([ '/404' ])
27 return false
28 }
29
30 if (account) {
31 this.router.navigate([ `/a/${actorName}` ], { skipLocationChange: true })
32 }
33
34 if (channel) {
35 this.router.navigate([ `/c/${actorName}` ], { skipLocationChange: true })
36 }
37
38 return true
39 })
40 )
41 }
42
43 private orUndefined () {
44 return catchError(() => of(undefined))
45 }
46}
diff --git a/client/src/app/shared/shared-main/router/index.ts b/client/src/app/shared/shared-main/router/index.ts
new file mode 100644
index 000000000..f4000b674
--- /dev/null
+++ b/client/src/app/shared/shared-main/router/index.ts
@@ -0,0 +1 @@
export * from './actor-redirect-guard.service'
diff --git a/client/src/app/shared/shared-main/shared-main.module.ts b/client/src/app/shared/shared-main/shared-main.module.ts
index f06f25ca5..c8dd01429 100644
--- a/client/src/app/shared/shared-main/shared-main.module.ts
+++ b/client/src/app/shared/shared-main/shared-main.module.ts
@@ -4,7 +4,7 @@ import { CommonModule, DatePipe } from '@angular/common'
4import { HttpClientModule } from '@angular/common/http' 4import { HttpClientModule } from '@angular/common/http'
5import { NgModule } from '@angular/core' 5import { NgModule } from '@angular/core'
6import { FormsModule, ReactiveFormsModule } from '@angular/forms' 6import { FormsModule, ReactiveFormsModule } from '@angular/forms'
7import { RouterModule } from '@angular/router' 7import { ActivatedRouteSnapshot, RouterModule } from '@angular/router'
8import { 8import {
9 NgbButtonsModule, 9 NgbButtonsModule,
10 NgbCollapseModule, 10 NgbCollapseModule,
@@ -17,7 +17,7 @@ import {
17import { LoadingBarModule } from '@ngx-loading-bar/core' 17import { LoadingBarModule } from '@ngx-loading-bar/core'
18import { LoadingBarHttpClientModule } from '@ngx-loading-bar/http-client' 18import { LoadingBarHttpClientModule } from '@ngx-loading-bar/http-client'
19import { SharedGlobalIconModule } from '../shared-icons' 19import { SharedGlobalIconModule } from '../shared-icons'
20import { AccountService, ActorService } from './account' 20import { AccountService } from './account'
21import { 21import {
22 AutofocusDirective, 22 AutofocusDirective,
23 BytesPipe, 23 BytesPipe,
@@ -39,6 +39,7 @@ import { UserHistoryService, UserNotificationsComponent, UserNotificationService
39import { RedundancyService, VideoImportService, VideoOwnershipService, VideoService } from './video' 39import { RedundancyService, VideoImportService, VideoOwnershipService, VideoService } from './video'
40import { VideoCaptionService } from './video-caption' 40import { VideoCaptionService } from './video-caption'
41import { VideoChannelService } from './video-channel' 41import { VideoChannelService } from './video-channel'
42import { ActorRedirectGuard } from './router'
42 43
43@NgModule({ 44@NgModule({
44 imports: [ 45 imports: [
@@ -161,7 +162,6 @@ import { VideoChannelService } from './video-channel'
161 AUTH_INTERCEPTOR_PROVIDER, 162 AUTH_INTERCEPTOR_PROVIDER,
162 163
163 AccountService, 164 AccountService,
164 ActorService,
165 165
166 UserHistoryService, 166 UserHistoryService,
167 UserNotificationService, 167 UserNotificationService,
@@ -175,7 +175,9 @@ import { VideoChannelService } from './video-channel'
175 175
176 VideoChannelService, 176 VideoChannelService,
177 177
178 CustomPageService 178 CustomPageService,
179
180 ActorRedirectGuard
179 ] 181 ]
180}) 182})
181export class SharedMainModule { } 183export class SharedMainModule { }