- ADR-0001: decision to extract auth/payment into shared @marketplaces/* packages - Scaffold packages/auth, packages/payment; @marketplaces/auth now holds the real telegram (customer+admin QR/session) and ed25519 (future admin challenge/response) auth implementation, pushed to sources.vitanova.network/sdarbinyan/vitanovaPackages - Rewire ~30 call sites to import from @marketplaces/auth; delete migrated originals from core/auth, core/admin-auth, services/, models/ - Replace environment coupling with AUTH_API_URL/TELEGRAM_BOT_USERNAME injection tokens and isDevMode(); wired as file:packages/auth pending registry publish - Add TRACK-S §8: bootstrap per-marketplace admin login + marketplace-scoped sub-admin invite/role endpoints - Build, arch:check:boundaries, and full test suite (103/103) all green Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
94 lines
3.6 KiB
TypeScript
94 lines
3.6 KiB
TypeScript
import { Component, ChangeDetectionStrategy, Input, Injector, Signal, inject, effect, OnDestroy, OnInit } from '@angular/core';
|
|
import { Router } from '@angular/router';
|
|
import { AuthService, AdminAuthService, AuthSession } from '@marketplaces/auth';
|
|
import { LanguageService } from '../../services/language.service';
|
|
import { TranslatePipe } from '../../i18n/translate.pipe';
|
|
import { QrLoginEngine } from '../../shared/qr-login/qr-login.engine';
|
|
import { QrLoginAdapter, QrLoginStatus } from '../../shared/qr-login/qr-login.model';
|
|
import { IconComponent } from '../../shared/ui/icon/icon.component';
|
|
|
|
/**
|
|
* The one QR-login dialog, reused as-is for both customer and admin login.
|
|
* `mode` only decides which session service/storage backs it (AuthService's
|
|
* customer session vs AdminAuthService's admin session) - the QR creation,
|
|
* polling, expiry, and "return from Telegram app" logic (QrLoginEngine) and
|
|
* the API call underneath it (TelegramSessionApiService) are identical for
|
|
* both, by design: there is one Telegram QR/session backend, not two.
|
|
*/
|
|
@Component({
|
|
selector: 'app-telegram-login',
|
|
imports: [TranslatePipe, IconComponent],
|
|
templateUrl: './telegram-login.component.html',
|
|
styleUrls: ['./telegram-login.component.scss'],
|
|
changeDetection: ChangeDetectionStrategy.OnPush
|
|
})
|
|
export class TelegramLoginComponent implements OnInit, OnDestroy {
|
|
@Input() mode: 'customer' | 'admin' = 'customer';
|
|
|
|
private readonly customerAuth = inject(AuthService);
|
|
private readonly adminAuth = inject(AdminAuthService);
|
|
private readonly injector = inject(Injector);
|
|
private readonly router = inject(Router);
|
|
private readonly languageService = inject(LanguageService);
|
|
|
|
private engine!: QrLoginEngine<AuthSession>;
|
|
|
|
showDialog = this.customerAuth.showLoginDialog;
|
|
status = this.customerAuth.status;
|
|
|
|
loginUrl!: Signal<string>;
|
|
webSessionID!: Signal<string>;
|
|
qrStatus!: Signal<QrLoginStatus>;
|
|
encodedQrUrl!: Signal<string>;
|
|
|
|
ngOnInit(): void {
|
|
const service = this.mode === 'admin' ? this.adminAuth : this.customerAuth;
|
|
this.showDialog = service.showLoginDialog;
|
|
this.status = service.status;
|
|
|
|
const adapter: QrLoginAdapter<AuthSession> = this.mode === 'admin'
|
|
? {
|
|
createSession: () => this.adminAuth.createWebSession(),
|
|
checkSessionOnce: id => this.adminAuth.checkSessionOnce(id),
|
|
isSessionActive: session => !!session?.active,
|
|
getAppLoginUrl: id => this.adminAuth.getAdminAppLoginUrl(id),
|
|
onLoginComplete: () => {
|
|
this.adminAuth.onLoginComplete();
|
|
void this.router.navigate([this.languageService.currentLanguage(), 'backoffice', 'dashboard']);
|
|
},
|
|
}
|
|
: {
|
|
createSession: () => this.customerAuth.createWebSession(),
|
|
checkSessionOnce: id => this.customerAuth.checkSessionOnce(id),
|
|
isSessionActive: session => !!session?.active,
|
|
getAppLoginUrl: id => this.customerAuth.getTelegramAppLoginUrl(id),
|
|
onLoginComplete: () => this.customerAuth.onTelegramLoginComplete(),
|
|
};
|
|
|
|
this.engine = new QrLoginEngine<AuthSession>(adapter);
|
|
this.loginUrl = this.engine.loginUrl;
|
|
this.webSessionID = this.engine.webSessionID;
|
|
this.qrStatus = this.engine.qrStatus;
|
|
this.encodedQrUrl = this.engine.encodedQrUrl;
|
|
|
|
effect(() => this.engine.setActive(this.showDialog()), { injector: this.injector });
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
this.engine?.destroy();
|
|
}
|
|
|
|
close(): void {
|
|
this.engine.setActive(false);
|
|
(this.mode === 'admin' ? this.adminAuth : this.customerAuth).hideLogin();
|
|
}
|
|
|
|
openTelegramLogin(): void {
|
|
this.engine.openAppLogin();
|
|
}
|
|
|
|
refreshQr(): void {
|
|
this.engine.refresh();
|
|
}
|
|
}
|