From 112e76ab452d9b0775ea7c898be6fb9c2bba7f89 Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Wed, 10 Jul 2024 16:35:14 +0300 Subject: [PATCH] feat: auth page --- apps/NwaifuAnime/src/app/app.config.ts | 4 +- apps/NwaifuAnime/src/app/app.routes.ts | 5 ++ .../app/components/auth/auth.component.html | 34 ++++++++++ .../app/components/auth/auth.component.less | 3 + .../src/app/components/auth/auth.component.ts | 58 ++++++++++++++++ .../src/app/components/auth/enum.ts | 3 + .../components/detail/detail.component.html | 66 ++++++++++--------- .../app/components/detail/detail.component.ts | 23 +++++-- .../rulib/lib.social.parser.service.ts | 34 +++++++--- .../parsers/rulib/rulib.auth.service.ts | 15 +++++ 10 files changed, 199 insertions(+), 46 deletions(-) create mode 100644 apps/NwaifuAnime/src/app/components/auth/auth.component.html create mode 100644 apps/NwaifuAnime/src/app/components/auth/auth.component.less create mode 100644 apps/NwaifuAnime/src/app/components/auth/auth.component.ts create mode 100644 apps/NwaifuAnime/src/app/components/auth/enum.ts create mode 100644 apps/NwaifuAnime/src/app/services/parsers/rulib/rulib.auth.service.ts diff --git a/apps/NwaifuAnime/src/app/app.config.ts b/apps/NwaifuAnime/src/app/app.config.ts index fd96c27..05a04f4 100644 --- a/apps/NwaifuAnime/src/app/app.config.ts +++ b/apps/NwaifuAnime/src/app/app.config.ts @@ -1,4 +1,4 @@ -import { provideHttpClient } from "@angular/common/http"; +import { provideHttpClient, withFetch } from "@angular/common/http"; import { ApplicationConfig, isDevMode, provideZoneChangeDetection } from "@angular/core"; import { provideRouter } from "@angular/router"; import { provideServiceWorker } from "@angular/service-worker"; @@ -12,6 +12,6 @@ export const appConfig: ApplicationConfig = { enabled: !isDevMode(), registrationStrategy: "registerWhenStable:30000", }), - provideHttpClient(), + provideHttpClient(withFetch()), ], }; diff --git a/apps/NwaifuAnime/src/app/app.routes.ts b/apps/NwaifuAnime/src/app/app.routes.ts index 58f6c8e..9e5c0e6 100644 --- a/apps/NwaifuAnime/src/app/app.routes.ts +++ b/apps/NwaifuAnime/src/app/app.routes.ts @@ -1,4 +1,5 @@ import { Route } from "@angular/router"; +import { AuthComponent } from "./components/auth/auth.component"; import { DetailComponent } from "./components/detail/detail.component"; import { HomeComponent } from "./components/home/home.component"; import { ReaderComponent } from "./components/reader/reader.component"; @@ -10,4 +11,8 @@ export const appRoutes: Route[] = [ }, { path: "detail", component: DetailComponent }, { path: "reader", component: ReaderComponent }, + { + path: "auth", + component: AuthComponent, + }, ]; diff --git a/apps/NwaifuAnime/src/app/components/auth/auth.component.html b/apps/NwaifuAnime/src/app/components/auth/auth.component.html new file mode 100644 index 0000000..7906acd --- /dev/null +++ b/apps/NwaifuAnime/src/app/components/auth/auth.component.html @@ -0,0 +1,34 @@ +
+
+

Авторизация в MangaLib

+
    +
  1. +

    Авторизация через токен

    +
    + + +
    +
  2. +
  3. + Вход через скрипт TamperMonkey. Если нет кнопки, значит вы не установили скрипт + + Вход + +
  4. +
+
+
diff --git a/apps/NwaifuAnime/src/app/components/auth/auth.component.less b/apps/NwaifuAnime/src/app/components/auth/auth.component.less new file mode 100644 index 0000000..fa58d9d --- /dev/null +++ b/apps/NwaifuAnime/src/app/components/auth/auth.component.less @@ -0,0 +1,3 @@ +.tamperMonkey { + display: none; +} diff --git a/apps/NwaifuAnime/src/app/components/auth/auth.component.ts b/apps/NwaifuAnime/src/app/components/auth/auth.component.ts new file mode 100644 index 0000000..b83cae7 --- /dev/null +++ b/apps/NwaifuAnime/src/app/components/auth/auth.component.ts @@ -0,0 +1,58 @@ +import { CommonModule } from "@angular/common"; +import { AfterViewInit, Component, ElementRef, OnDestroy, ViewChild } from "@angular/core"; +import { ActivatedRoute, Router, RouterLink } from "@angular/router"; +import { Subject, takeUntil } from "rxjs"; +import { RulibAuthService } from "../../services/parsers/rulib/rulib.auth.service"; +import { EAuthTokenService } from "./enum"; + +@Component({ + selector: "app-auth", + templateUrl: "./auth.component.html", + styleUrls: ["./auth.component.less"], + standalone: true, + imports: [CommonModule, RouterLink], +}) +export class AuthComponent implements AfterViewInit, OnDestroy { + private destroy$ = new Subject(); + @ViewChild("libSocialToken") libSocialToken: ElementRef | null = null; + constructor( + private route: ActivatedRoute, + private router: Router, + private rulibAuthService: RulibAuthService, + ) {} + + private setToken(service: EAuthTokenService, token: string) { + switch (service) { + case EAuthTokenService.RULIB: + this.rulibAuthService.setToken(token); + break; + default: + this.router.navigate(["/", "auth"]); + return; + } + this.router.navigate(["/"]); + } + + setLibSocialToken() { + if (this.libSocialToken) { + const token = this.libSocialToken.nativeElement.value; + this.setToken(EAuthTokenService.RULIB, token); + } + } + + ngAfterViewInit(): void { + this.route.queryParams.pipe(takeUntil(this.destroy$)).subscribe((params) => { + const { token, service } = params; + if (token && service) { + this.setToken(service as EAuthTokenService, token); + } + }); + if (this.libSocialToken) { + this.libSocialToken.nativeElement.value = this.rulibAuthService.getToken(); + } + } + ngOnDestroy(): void { + this.destroy$.next(); + this.destroy$.complete(); + } +} diff --git a/apps/NwaifuAnime/src/app/components/auth/enum.ts b/apps/NwaifuAnime/src/app/components/auth/enum.ts new file mode 100644 index 0000000..85a7e8a --- /dev/null +++ b/apps/NwaifuAnime/src/app/components/auth/enum.ts @@ -0,0 +1,3 @@ +export enum EAuthTokenService { + RULIB = "rulib", +} diff --git a/apps/NwaifuAnime/src/app/components/detail/detail.component.html b/apps/NwaifuAnime/src/app/components/detail/detail.component.html index 53c86e3..ca1826c 100644 --- a/apps/NwaifuAnime/src/app/components/detail/detail.component.html +++ b/apps/NwaifuAnime/src/app/components/detail/detail.component.html @@ -1,38 +1,44 @@
+ @if (needAuth) { +

Необходима авторизация

+ Войти + } @if (detail_item) {

{{ detail_item.name }}

{{ detail_item.rus_name }}

-
- -

Главы

-
-
- @for (chapter of chapters.data; track $index) { - -

- {{ chapter.number }}. {{ chapter.name || "Нет названия" }} -

-
- } -
-
- - Читать - + @if (!needAuth) { +
+ +

Главы

+
+
+ @for (chapter of chapters.data; track $index) { + +

+ {{ chapter.number }}. {{ chapter.name || "Нет названия" }} +

+
+ } +
+
+ + Читать + + } }
diff --git a/apps/NwaifuAnime/src/app/components/detail/detail.component.ts b/apps/NwaifuAnime/src/app/components/detail/detail.component.ts index 62b5879..4dd1d59 100644 --- a/apps/NwaifuAnime/src/app/components/detail/detail.component.ts +++ b/apps/NwaifuAnime/src/app/components/detail/detail.component.ts @@ -16,6 +16,7 @@ import { SearchService } from "../../services/search.service"; export class DetailComponent implements AfterViewInit, OnDestroy { detail_item: Data | null = null; chapters: IRulibChaptersResult = { data: [] }; + needAuth: boolean = false; private destroy$ = new Subject(); constructor( private route: ActivatedRoute, @@ -27,15 +28,27 @@ export class DetailComponent implements AfterViewInit, OnDestroy { this.searchService .getDetails(url) .pipe(takeUntil(this.destroy$)) - .subscribe((data) => { - this.detail_item = data.data; + .subscribe({ + next: (data) => { + this.detail_item = data.data; + }, + error: (error) => { + console.log(error); + }, }); this.searchService .getChapters(url) .pipe(takeUntil(this.destroy$)) - .subscribe((data) => { - this.chapters = data; - console.log(data); + .subscribe({ + next: (data) => { + this.chapters = data; + if (data.data.length === 0) { + this.needAuth = true; + } + }, + error: (error) => { + console.log(error); + }, }); } diff --git a/apps/NwaifuAnime/src/app/services/parsers/rulib/lib.social.parser.service.ts b/apps/NwaifuAnime/src/app/services/parsers/rulib/lib.social.parser.service.ts index 98df4bb..c549a13 100644 --- a/apps/NwaifuAnime/src/app/services/parsers/rulib/lib.social.parser.service.ts +++ b/apps/NwaifuAnime/src/app/services/parsers/rulib/lib.social.parser.service.ts @@ -1,6 +1,8 @@ +import { HttpClient } from "@angular/common/http"; import { Injectable } from "@angular/core"; import { Observable, catchError, map, throwError } from "rxjs"; import { Parser } from "../parser"; +import { RulibAuthService } from "./rulib.auth.service"; import { IRulibChapterResult } from "./rulib.chapter.dto"; import { IRulibChaptersResult } from "./rulib.chapters.dto"; import { IRulibDetailResult } from "./rulib.detail.dto"; @@ -19,6 +21,13 @@ export class LibSocialParserService extends Parser { return "https://img33.imgslib.link"; } + constructor( + private rulibAuthService: RulibAuthService, + override http: HttpClient, + ) { + super(http); + } + searchManga(query: string): Observable { return this.http .get( @@ -38,6 +47,7 @@ export class LibSocialParserService extends Parser { return this.http .get( `${this.url}/api/manga/${slug_url}?fields[]=summary&fields[]=genres&fields[]=tags&fields[]=authors`, + { headers: { Authorization: "Bearer " + this.rulibAuthService.getToken() } }, ) .pipe( map((data: object) => { @@ -50,19 +60,25 @@ export class LibSocialParserService extends Parser { } getChapters(url: string): Observable { - return this.http.get(`${this.url}/api/manga/${url}/chapters`).pipe( - map((data) => { - return data as IRulibChaptersResult; - }), - catchError((error) => { - return throwError(() => `Now found ${error}`); - }), - ); + return this.http + .get(`${this.url}/api/manga/${url}/chapters`, { + headers: { Authorization: "Bearer " + this.rulibAuthService.getToken() }, + }) + .pipe( + map((data) => { + return data as IRulibChaptersResult; + }), + catchError((error) => { + return throwError(() => `Now found ${error}`); + }), + ); } getChapter(url: string, chapter: string, volume: string): Observable { return this.http - .get(`${this.url}/api/manga/${url}/chapter?number=${chapter}&volume=${volume}`) + .get(`${this.url}/api/manga/${url}/chapter?number=${chapter}&volume=${volume}`, { + headers: { Authorization: "Bearer " + this.rulibAuthService.getToken() }, + }) .pipe( map((data) => data as IRulibChapterResult), catchError((error) => throwError(() => `Now found ${error}`)), diff --git a/apps/NwaifuAnime/src/app/services/parsers/rulib/rulib.auth.service.ts b/apps/NwaifuAnime/src/app/services/parsers/rulib/rulib.auth.service.ts new file mode 100644 index 0000000..0708796 --- /dev/null +++ b/apps/NwaifuAnime/src/app/services/parsers/rulib/rulib.auth.service.ts @@ -0,0 +1,15 @@ +import { Injectable } from "@angular/core"; +@Injectable({ + providedIn: "root", +}) +export class RulibAuthService { + setToken(token: string) { + localStorage.setItem("token", token); + } + + getToken(): string { + return localStorage.getItem("token") ?? ""; + } + + //TODO: Проверка токена +}