138 lines
3.6 KiB
Markdown
138 lines
3.6 KiB
Markdown
# telegram-userauth
|
|
|
|
Reusable Telegram authentication package built as a web component for drop-in use across other repos.
|
|
|
|
It ships a custom element named `telegram-userauth` that:
|
|
|
|
- checks `GET /userauth/session` on startup
|
|
- creates a QR session with `POST /userauth/qr/create`
|
|
- polls `GET /userauth/qr/poll?token=...` every 5 seconds by default
|
|
- emits browser events when auth state changes, when login succeeds, and when backend calls fail
|
|
- works with same-origin APIs or a separate API origin through `apiBaseUrl`
|
|
|
|
## Install
|
|
|
|
```bash
|
|
npm install telegram-userauth
|
|
```
|
|
|
|
## Use in another repo
|
|
|
|
Register the custom element once in your app entrypoint:
|
|
|
|
```ts
|
|
import { defineTelegramUserAuthElement } from 'telegram-userauth';
|
|
|
|
defineTelegramUserAuthElement();
|
|
```
|
|
|
|
Render it anywhere in your app:
|
|
|
|
```html
|
|
<telegram-userauth api-base-url="https://api.example.com"></telegram-userauth>
|
|
```
|
|
|
|
Listen for successful login:
|
|
|
|
```ts
|
|
const element = document.querySelector('telegram-userauth');
|
|
|
|
element?.addEventListener('userauth-authenticated', (event) => {
|
|
const detail = (event as CustomEvent).detail;
|
|
console.log('Authenticated session', detail.session);
|
|
});
|
|
```
|
|
|
|
## Element attributes
|
|
|
|
- `api-base-url`: backend origin, for example `https://api.example.com`. Leave empty for same-origin `/userauth/...`.
|
|
- `telegram-login-url`: optional direct Telegram button URL. If omitted, the button opens the deep link returned by `POST /userauth/qr/create`.
|
|
- `poll-interval-ms`: polling interval in milliseconds. Default: `5000`.
|
|
- `max-poll-attempts`: maximum QR poll attempts before the QR becomes expired. Default: `100`.
|
|
- `qr-size`: QR image size in pixels. Default: `220`.
|
|
- `title`: heading text.
|
|
- `description`: description text shown before authentication.
|
|
- `auto-start`: `true` by default. Set to `false` if the host app wants to call `element.start()` manually.
|
|
|
|
## Custom events
|
|
|
|
- `userauth-authenticated`: detail `{ session }`
|
|
- `userauth-statechange`: detail `{ state }`
|
|
- `userauth-error`: detail `{ message }`
|
|
|
|
## Imperative API
|
|
|
|
After selecting the element, the host app can call:
|
|
|
|
- `await element.start()`
|
|
- `await element.refresh()`
|
|
- `element.currentSession`
|
|
- `element.options = { apiBaseUrl: 'https://api.example.com' }`
|
|
|
|
## Example integrations
|
|
|
|
### React / Next / Vite
|
|
|
|
```ts
|
|
import { useEffect } from 'react';
|
|
import { defineTelegramUserAuthElement } from 'telegram-userauth';
|
|
|
|
export function TelegramAuth() {
|
|
useEffect(() => {
|
|
defineTelegramUserAuthElement();
|
|
}, []);
|
|
|
|
return <telegram-userauth api-base-url="https://api.example.com" />;
|
|
}
|
|
```
|
|
|
|
### Angular host app
|
|
|
|
```ts
|
|
import { CUSTOM_ELEMENTS_SCHEMA, Component } from '@angular/core';
|
|
import { defineTelegramUserAuthElement } from 'telegram-userauth';
|
|
|
|
defineTelegramUserAuthElement();
|
|
|
|
@Component({
|
|
selector: 'app-auth-page',
|
|
template: '<telegram-userauth api-base-url="https://api.example.com"></telegram-userauth>',
|
|
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
|
})
|
|
export class AuthPageComponent {}
|
|
```
|
|
|
|
## Local development
|
|
|
|
```bash
|
|
npm start
|
|
```
|
|
|
|
The local Angular app is only a preview host for the package and runs on port `4300`.
|
|
|
|
## Build
|
|
|
|
```bash
|
|
npm run build
|
|
```
|
|
|
|
This builds both the preview app and the publishable package.
|
|
|
|
To build only the package output:
|
|
|
|
```bash
|
|
npm run build:package
|
|
```
|
|
|
|
## Backend contract
|
|
|
|
The backend requirements are documented in [TELEGRAM_USERAUTH_BACKEND.md](TELEGRAM_USERAUTH_BACKEND.md).
|
|
|
|
Key expectations:
|
|
|
|
- cookie name `userauth_session`
|
|
- credentialed CORS when frontend and backend are on different origins
|
|
- exact session response shape
|
|
- `POST /userauth/qr/create` returns `{ token, url }`
|
|
- `GET /userauth/qr/poll` returns `pending`, `confirmed`, or `expired`
|