var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { Injectable, inject } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { of, catchError, map } from 'rxjs'; import { AUTH_API_URL, TELEGRAM_BOT_USERNAME } from '../config'; import { generateGuid } from '../util/guid.util'; const SESSION_MAX_AGE_SECONDS = 60 * 60; const DEFAULT_TELEGRAM_BOT_USERNAME = 'DexarSupport_bot'; /** * The one Telegram QR/session API (`{authApiUrl}/users/sessions`). Customer * login (AuthService) and admin login (AdminAuthService) both call this same * service against this same endpoint - there is no separate admin backend. * This class only does the HTTP call + response normalization; it holds no * session state and writes no cookies, so each caller manages its own * storage/signals independently on top of it. */ let TelegramSessionApiService = class TelegramSessionApiService { constructor() { this.http = inject(HttpClient); this.authApiUrl = inject(AUTH_API_URL); this.telegramBotUsername = inject(TELEGRAM_BOT_USERNAME, { optional: true }); } createSession() { const webSessionID = generateGuid(); return this.http.post(`${this.authApiUrl}/users/sessions`, { webSessionID }, { headers: { WebSessionID: webSessionID } }).pipe(map(response => { const responseWebSessionID = this.extractSessionId(response, webSessionID); return { webSessionID: responseWebSessionID, url: this.getBotLoginUrl(responseWebSessionID), }; })); } checkSessionOnce(webSessionID) { if (!webSessionID) { return of(null); } return this.http.get(`${this.authApiUrl}/users/sessions/${encodeURIComponent(webSessionID)}`).pipe(map(response => this.normalizeWebSession(response, webSessionID)), catchError(() => of(null))); } logout(webSessionID) { return this.http.delete(`${this.authApiUrl}/users/sessions/${encodeURIComponent(webSessionID)}`, { headers: { WebSessionID: webSessionID } }).pipe(catchError(() => of(null))); } getBotLoginUrl(webSessionID) { return `https://t.me/${this.getBotUsername()}?start=${encodeURIComponent(webSessionID)}`; } getBotAppLoginUrl(webSessionID) { return `tg://resolve?domain=${encodeURIComponent(this.getBotUsername())}&start=${encodeURIComponent(webSessionID)}`; } getBotUsername() { return this.telegramBotUsername || DEFAULT_TELEGRAM_BOT_USERNAME; } normalizeWebSession(response, fallbackSessionId) { if (!response) { return null; } const user = this.asRecord(this.readFirst(response, ['user', 'User', 'telegramUser', 'TelegramUser'])) ?? response; const status = this.readFirst(response, [ 'status', 'Status', 'active', 'Active', 'loggedIn', 'LoggedIn', 'isLoggedIn', 'IsLoggedIn', 'authenticated', 'Authenticated' ]); const active = this.isActiveStatus(status); const sessionId = this.extractSessionId(response, fallbackSessionId); const username = this.readString(this.readFirst(user, ['username', 'Username'])) ?? this.readString(this.readFirst(response, ['username', 'Username'])); const firstName = this.readString(this.readFirst(user, ['firstName', 'first_name', 'FirstName', 'First_name'])); const lastName = this.readString(this.readFirst(user, ['lastName', 'last_name', 'LastName', 'Last_name'])); const fullName = [firstName, lastName].filter(Boolean).join(' '); const explicitDisplayName = this.readString(this.readFirst(response, ['displayName', 'DisplayName', 'name', 'Name'])) ?? this.readString(this.readFirst(user, ['displayName', 'DisplayName', 'name', 'Name'])); const displayName = explicitDisplayName ?? username ?? (fullName || 'Telegram User'); const telegramUserId = this.readNumber(this.readFirst(user, ['userId', 'telegramUserId', 'telegramUserID', 'TelegramUserID', 'id', 'ID'])) ?? this.readNumber(this.readFirst(response, ['userId', 'telegramUserId', 'telegramUserID', 'TelegramUserID', 'userID', 'UserID', 'UserId'])) ?? null; const expiresAt = this.readString(this.readFirst(response, ['expiresAt', 'ExpiresAt', 'expires', 'Expires'])) ?? new Date(Date.now() + SESSION_MAX_AGE_SECONDS * 1000).toISOString(); return { sessionId, userId: telegramUserId, username, displayName, active, expires: expiresAt }; } extractSessionId(response, fallbackSessionId) { if (!response) { return fallbackSessionId; } return this.readString(this.readFirst(response, [ 'webSessionID', 'WebSessionID', 'webSessionId', 'sessionID', 'SessionID', 'sessionId', 'id', 'ID' ])) ?? fallbackSessionId; } readFirst(source, keys) { for (const key of keys) { if (Object.prototype.hasOwnProperty.call(source, key)) { return source[key]; } } return undefined; } readString(value) { if (typeof value === 'string' && value.trim()) { return value; } if (typeof value === 'number' || typeof value === 'bigint') { return value.toString(); } return null; } readNumber(value) { if (typeof value === 'number' && Number.isFinite(value)) { return value; } if (typeof value === 'string') { const parsed = Number(value); return Number.isFinite(parsed) ? parsed : null; } return null; } asRecord(value) { return value !== null && typeof value === 'object' && !Array.isArray(value) ? value : null; } isActiveStatus(status) { if (status === true || status === 1) { return true; } if (typeof status !== 'string') { return false; } return ['true', '1', 'active', 'authenticated', 'confirmed', 'success', 'logged_in'].includes(status.toLowerCase()); } }; TelegramSessionApiService = __decorate([ Injectable({ providedIn: 'root' }) ], TelegramSessionApiService); export { TelegramSessionApiService };