@telegram-login-ultimate/core 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Erik
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,113 @@
1
+ //#region src/client.d.ts
2
+ interface PopupOptions {
3
+ /**
4
+ * Height of the popup
5
+ */
6
+ height: number;
7
+ /**
8
+ * Width of the popup
9
+ */
10
+ width: number;
11
+ }
12
+ /**
13
+ * Data returned after a successful Telegram login authentication.
14
+ */
15
+ interface TelegramUserData {
16
+ /**
17
+ * Unix timestamp indicating when the authentication occurred.
18
+ */
19
+ auth_date: number;
20
+ /**
21
+ * User's first name.
22
+ */
23
+ first_name: string;
24
+ /**
25
+ * Data hash for verification of the authentication data integrity.
26
+ */
27
+ hash: string;
28
+ /**
29
+ * Unique identifier for the user.
30
+ */
31
+ id: number;
32
+ /**
33
+ * User's last name, if available.
34
+ */
35
+ last_name?: string;
36
+ /**
37
+ * URL of the user's profile photo, if available.
38
+ */
39
+ photo_url?: string;
40
+ /**
41
+ * User's username, if available.
42
+ */
43
+ username?: string;
44
+ }
45
+ /**
46
+ * Configuration options for the Telegram login client.
47
+ */
48
+ interface TelegramLoginClientOptions {
49
+ /**
50
+ * Default popup window dimensions that will be used when no specific popup options are provided in the login method.
51
+ * @default { width: 550, height: 470 }
52
+ */
53
+ defaultPopupOptions?: PopupOptions;
54
+ }
55
+ /**
56
+ * Configuration options for the Telegram login method.
57
+ */
58
+ interface LoginOptions {
59
+ /**
60
+ * The unique identifier of the Telegram bot. You can obtain it from the https://t.me/username_to_id_bot.
61
+ */
62
+ botId: number;
63
+ /**
64
+ * Optional popup window configuration. If not provided, default popup options will be used.
65
+ */
66
+ popup?: Partial<PopupOptions>;
67
+ /**
68
+ * Optional callback function that will be called if an error occurs during the login process.
69
+ * @param {unknown} error - The error that occurred.
70
+ */
71
+ onError?: (error: unknown) => void;
72
+ /**
73
+ * Optional callback function that will be called when the login process starts.
74
+ */
75
+ onStart?: () => void;
76
+ /**
77
+ * Optional callback function that will be called when the login process completes successfully.
78
+ * @param {TelegramUserData} data - The authentication data returned from Telegram.
79
+ */
80
+ onSuccess?: (data: TelegramUserData) => void;
81
+ }
82
+ /**
83
+ * Telegram login client.
84
+ */
85
+ declare class TelegramLoginClient {
86
+ private defaultPopupOptions;
87
+ private popups;
88
+ /**
89
+ * Create a new Telegram login client.
90
+ * @param {TelegramLoginClientOptions} options - Configuration options for the Telegram login client.
91
+ */
92
+ constructor(options?: TelegramLoginClientOptions);
93
+ /**
94
+ * Opens a popup window for the user to log in to Telegram.
95
+ * @param {LoginOptions} options
96
+ * @returns {void}
97
+ */
98
+ login(options: LoginOptions): void;
99
+ private getAuthData;
100
+ private openPopup;
101
+ }
102
+ //#endregion
103
+ //#region src/exceptions.d.ts
104
+ declare class AuthenticationError extends Error {}
105
+ /**
106
+ * Function to check if an error is an instance of AuthenticationError.
107
+ *
108
+ * @param {unknown} error
109
+ */
110
+ declare function isAuthenticationError(error: unknown): error is AuthenticationError;
111
+ //#endregion
112
+ export { type LoginOptions, type PopupOptions, TelegramLoginClient, type TelegramLoginClientOptions, type TelegramUserData, isAuthenticationError };
113
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1,113 @@
1
+ //#region src/client.d.ts
2
+ interface PopupOptions {
3
+ /**
4
+ * Height of the popup
5
+ */
6
+ height: number;
7
+ /**
8
+ * Width of the popup
9
+ */
10
+ width: number;
11
+ }
12
+ /**
13
+ * Data returned after a successful Telegram login authentication.
14
+ */
15
+ interface TelegramUserData {
16
+ /**
17
+ * Unix timestamp indicating when the authentication occurred.
18
+ */
19
+ auth_date: number;
20
+ /**
21
+ * User's first name.
22
+ */
23
+ first_name: string;
24
+ /**
25
+ * Data hash for verification of the authentication data integrity.
26
+ */
27
+ hash: string;
28
+ /**
29
+ * Unique identifier for the user.
30
+ */
31
+ id: number;
32
+ /**
33
+ * User's last name, if available.
34
+ */
35
+ last_name?: string;
36
+ /**
37
+ * URL of the user's profile photo, if available.
38
+ */
39
+ photo_url?: string;
40
+ /**
41
+ * User's username, if available.
42
+ */
43
+ username?: string;
44
+ }
45
+ /**
46
+ * Configuration options for the Telegram login client.
47
+ */
48
+ interface TelegramLoginClientOptions {
49
+ /**
50
+ * Default popup window dimensions that will be used when no specific popup options are provided in the login method.
51
+ * @default { width: 550, height: 470 }
52
+ */
53
+ defaultPopupOptions?: PopupOptions;
54
+ }
55
+ /**
56
+ * Configuration options for the Telegram login method.
57
+ */
58
+ interface LoginOptions {
59
+ /**
60
+ * The unique identifier of the Telegram bot. You can obtain it from the https://t.me/username_to_id_bot.
61
+ */
62
+ botId: number;
63
+ /**
64
+ * Optional popup window configuration. If not provided, default popup options will be used.
65
+ */
66
+ popup?: Partial<PopupOptions>;
67
+ /**
68
+ * Optional callback function that will be called if an error occurs during the login process.
69
+ * @param {unknown} error - The error that occurred.
70
+ */
71
+ onError?: (error: unknown) => void;
72
+ /**
73
+ * Optional callback function that will be called when the login process starts.
74
+ */
75
+ onStart?: () => void;
76
+ /**
77
+ * Optional callback function that will be called when the login process completes successfully.
78
+ * @param {TelegramUserData} data - The authentication data returned from Telegram.
79
+ */
80
+ onSuccess?: (data: TelegramUserData) => void;
81
+ }
82
+ /**
83
+ * Telegram login client.
84
+ */
85
+ declare class TelegramLoginClient {
86
+ private defaultPopupOptions;
87
+ private popups;
88
+ /**
89
+ * Create a new Telegram login client.
90
+ * @param {TelegramLoginClientOptions} options - Configuration options for the Telegram login client.
91
+ */
92
+ constructor(options?: TelegramLoginClientOptions);
93
+ /**
94
+ * Opens a popup window for the user to log in to Telegram.
95
+ * @param {LoginOptions} options
96
+ * @returns {void}
97
+ */
98
+ login(options: LoginOptions): void;
99
+ private getAuthData;
100
+ private openPopup;
101
+ }
102
+ //#endregion
103
+ //#region src/exceptions.d.ts
104
+ declare class AuthenticationError extends Error {}
105
+ /**
106
+ * Function to check if an error is an instance of AuthenticationError.
107
+ *
108
+ * @param {unknown} error
109
+ */
110
+ declare function isAuthenticationError(error: unknown): error is AuthenticationError;
111
+ //#endregion
112
+ export { type LoginOptions, type PopupOptions, TelegramLoginClient, type TelegramLoginClientOptions, type TelegramUserData, isAuthenticationError };
113
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ const e=`https://oauth.telegram.org`;var t=class extends Error{};function n(e){return e instanceof t}const r=(e,t)=>{let n=new URLSearchParams;for(let[e,r]of Object.entries(t))n.append(e,r.toString());return`${e}?${n.toString()}`};var i=class{defaultPopupOptions;popups={};constructor(e){this.defaultPopupOptions=e?.defaultPopupOptions??{width:550,height:470}}login(e){let{botId:n,popup:r,onStart:i,onSuccess:a,onError:o}=e,s=r?.width??this.defaultPopupOptions.width,c=r?.height??this.defaultPopupOptions.height,l=this.openPopup(n,{width:s,height:c}),u=({data:e,error:t})=>{let r=this.popups[n];!r||r.authFinished||(r.authFinished=!0,e?a?.(e):o?.(t))},d=e=>{let r=this.popups[n];if(!r||e.source!==r.window)return;let i=JSON.parse(e.data);i.event===`auth_result`&&(u(i.result?{data:i.result,error:null}:{data:null,error:new t}),window.removeEventListener(`message`,d))},f=async()=>{let e=this.popups[n];if(!e||e.authFinished)return;if(!e.window.closed){setTimeout(f,100);return}let r;try{let e=await this.getAuthData(n);r=`user`in e?{data:e.user,error:null}:{data:null,error:new t(e.error)}}catch(e){r={data:null,error:e}}u(r),window.removeEventListener(`message`,d)};if(l){let e=this.popups[n]?.window.closed===!1;this.popups[n]={window:l,authFinished:!1},l.focus(),e||(window.addEventListener(`message`,d),f(),i?.())}}async getAuthData(t){let n=r(`${e}/auth/get`,{bot_id:t});return await(await fetch(n,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded; charset=UTF-8`,"X-Requested-With":`XMLHttpRequest`},credentials:`include`})).json()}openPopup(t,{width:n,height:i}){let a=Math.max(0,(screen.width-n)/2)+screen.availWidth,o=Math.max(0,(screen.height-i)/2)+screen.availHeight,s=r(`${e}/auth`,{bot_id:t,origin:location.origin||`${location.protocol}//${location.hostname}`,return_to:location.href});return window.open(s,`telegram_oauth_bot${t}`,`width=${n},height=${i},left=${a},top=${o},status=0,location=0,menubar=0,toolbar=0`)}};exports.TelegramLoginClient=i,exports.isAuthenticationError=n;
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["popup","data: {\n event: string\n result: false | TelegramUserData\n }","result: AuthResult"],"sources":["../src/consts.ts","../src/exceptions.ts","../src/utils.ts","../src/client.ts"],"sourcesContent":["export const POPUP_ORIGIN = 'https://oauth.telegram.org'\n","export class AuthenticationError extends Error {}\n\n/**\n * Function to check if an error is an instance of AuthenticationError.\n *\n * @param {unknown} error\n */\nexport function isAuthenticationError(\n error: unknown,\n): error is AuthenticationError {\n return error instanceof AuthenticationError\n}\n","export const buildUrl = (\n base: string,\n params: Record<string, boolean | number | string>,\n): string => {\n const searchParams = new URLSearchParams()\n\n for (const [key, value] of Object.entries(params)) {\n searchParams.append(key, value.toString())\n }\n\n return `${base}?${searchParams.toString()}`\n}\n","import { POPUP_ORIGIN } from './consts'\nimport { AuthenticationError } from './exceptions'\nimport { buildUrl } from './utils'\n\nexport interface PopupOptions {\n /**\n * Height of the popup\n */\n height: number\n /**\n * Width of the popup\n */\n width: number\n}\n\ninterface PopupInstance {\n authFinished: boolean\n window: Window\n}\n\ntype GetAuthResponse = (\n | { error: string }\n | { user: TelegramUserData }\n) & {\n html: string\n origin: string\n}\n\ntype AuthResult =\n | { data: null; error: Error }\n | { data: TelegramUserData; error: null }\n\n/**\n * Data returned after a successful Telegram login authentication.\n */\nexport interface TelegramUserData {\n /**\n * Unix timestamp indicating when the authentication occurred.\n */\n auth_date: number\n /**\n * User's first name.\n */\n first_name: string\n /**\n * Data hash for verification of the authentication data integrity.\n */\n hash: string\n /**\n * Unique identifier for the user.\n */\n id: number\n /**\n * User's last name, if available.\n */\n last_name?: string\n /**\n * URL of the user's profile photo, if available.\n */\n photo_url?: string\n /**\n * User's username, if available.\n */\n username?: string\n}\n\n/**\n * Configuration options for the Telegram login client.\n */\nexport interface TelegramLoginClientOptions {\n /**\n * Default popup window dimensions that will be used when no specific popup options are provided in the login method.\n * @default { width: 550, height: 470 }\n */\n defaultPopupOptions?: PopupOptions\n}\n\n/**\n * Configuration options for the Telegram login method.\n */\nexport interface LoginOptions {\n /**\n * The unique identifier of the Telegram bot. You can obtain it from the https://t.me/username_to_id_bot.\n */\n botId: number\n /**\n * Optional popup window configuration. If not provided, default popup options will be used.\n */\n popup?: Partial<PopupOptions>\n /**\n * Optional callback function that will be called if an error occurs during the login process.\n * @param {unknown} error - The error that occurred.\n */\n onError?: (error: unknown) => void\n /**\n * Optional callback function that will be called when the login process starts.\n */\n onStart?: () => void\n /**\n * Optional callback function that will be called when the login process completes successfully.\n * @param {TelegramUserData} data - The authentication data returned from Telegram.\n */\n onSuccess?: (data: TelegramUserData) => void\n}\n\n/**\n * Telegram login client.\n */\nexport class TelegramLoginClient {\n private defaultPopupOptions: PopupOptions\n private popups: Partial<Record<number, PopupInstance>> = {}\n\n /**\n * Create a new Telegram login client.\n * @param {TelegramLoginClientOptions} options - Configuration options for the Telegram login client.\n */\n constructor(options?: TelegramLoginClientOptions) {\n this.defaultPopupOptions = options?.defaultPopupOptions ?? {\n width: 550,\n height: 470,\n }\n }\n\n /**\n * Opens a popup window for the user to log in to Telegram.\n * @param {LoginOptions} options\n * @returns {void}\n */\n login(options: LoginOptions): void {\n const {\n botId,\n popup: popupOptions,\n onStart,\n onSuccess,\n onError,\n } = options\n\n const width =\n popupOptions?.width ?? this.defaultPopupOptions.width\n const height =\n popupOptions?.height ?? this.defaultPopupOptions.height\n\n const popup = this.openPopup(botId, { width, height })\n\n const handleAuth = ({ data, error }: AuthResult): void => {\n const popup = this.popups[botId]\n if (!popup || popup.authFinished) return\n popup.authFinished = true\n\n if (data) {\n onSuccess?.(data)\n } else {\n onError?.(error)\n }\n }\n\n const handleMessage = (event: MessageEvent<string>): void => {\n const popup = this.popups[botId]\n if (!popup) return\n if (event.source !== popup.window) return\n\n const data: {\n event: string\n result: false | TelegramUserData\n } = JSON.parse(event.data)\n\n if (data.event === 'auth_result') {\n const result = data.result\n ? { data: data.result, error: null }\n : { data: null, error: new AuthenticationError() }\n\n handleAuth(result)\n window.removeEventListener('message', handleMessage)\n }\n }\n\n const checkClose = async (): Promise<void> => {\n const popup = this.popups[botId]\n\n if (!popup || popup.authFinished) return\n if (!popup.window.closed) {\n setTimeout(checkClose, 100)\n return\n }\n\n let result: AuthResult\n\n try {\n const response = await this.getAuthData(botId)\n result =\n 'user' in response\n ? {\n data: response.user,\n error: null,\n }\n : {\n data: null,\n error: new AuthenticationError(response.error),\n }\n } catch (error) {\n // Casting error to Error type because it cannot be another type\n result = { data: null, error: error as Error }\n }\n\n handleAuth(result)\n window.removeEventListener('message', handleMessage)\n }\n\n if (popup) {\n const isPopupAlreadyExists =\n this.popups[botId]?.window.closed === false\n\n this.popups[botId] = { window: popup, authFinished: false }\n popup.focus()\n\n if (!isPopupAlreadyExists) {\n window.addEventListener('message', handleMessage)\n checkClose()\n onStart?.()\n }\n }\n }\n\n private async getAuthData(botId: number): Promise<GetAuthResponse> {\n const url = buildUrl(`${POPUP_ORIGIN}/auth/get`, {\n bot_id: botId,\n })\n const headers = {\n 'Content-Type':\n 'application/x-www-form-urlencoded; charset=UTF-8',\n 'X-Requested-With': 'XMLHttpRequest',\n }\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n credentials: 'include',\n })\n\n return await response.json()\n }\n\n private openPopup(\n botId: number,\n { width, height }: PopupOptions,\n ): WindowProxy | null {\n const left =\n Math.max(0, (screen.width - width) / 2) + screen.availWidth\n const top =\n Math.max(0, (screen.height - height) / 2) + screen.availHeight\n\n const popupUrl = buildUrl(`${POPUP_ORIGIN}/auth`, {\n bot_id: botId,\n origin:\n location.origin ||\n `${location.protocol}//${location.hostname}`,\n return_to: location.href,\n })\n\n return window.open(\n popupUrl,\n `telegram_oauth_bot${botId}`,\n `width=${width},height=${height},left=${left},top=${\n top\n },status=0,location=0,menubar=0,toolbar=0`,\n )\n }\n}\n"],"mappings":"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"}
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ const e=`https://oauth.telegram.org`;var t=class extends Error{};function n(e){return e instanceof t}const r=(e,t)=>{let n=new URLSearchParams;for(let[e,r]of Object.entries(t))n.append(e,r.toString());return`${e}?${n.toString()}`};var i=class{defaultPopupOptions;popups={};constructor(e){this.defaultPopupOptions=e?.defaultPopupOptions??{width:550,height:470}}login(e){let{botId:n,popup:r,onStart:i,onSuccess:a,onError:o}=e,s=r?.width??this.defaultPopupOptions.width,c=r?.height??this.defaultPopupOptions.height,l=this.openPopup(n,{width:s,height:c}),u=({data:e,error:t})=>{let r=this.popups[n];!r||r.authFinished||(r.authFinished=!0,e?a?.(e):o?.(t))},d=e=>{let r=this.popups[n];if(!r||e.source!==r.window)return;let i=JSON.parse(e.data);i.event===`auth_result`&&(u(i.result?{data:i.result,error:null}:{data:null,error:new t}),window.removeEventListener(`message`,d))},f=async()=>{let e=this.popups[n];if(!e||e.authFinished)return;if(!e.window.closed){setTimeout(f,100);return}let r;try{let e=await this.getAuthData(n);r=`user`in e?{data:e.user,error:null}:{data:null,error:new t(e.error)}}catch(e){r={data:null,error:e}}u(r),window.removeEventListener(`message`,d)};if(l){let e=this.popups[n]?.window.closed===!1;this.popups[n]={window:l,authFinished:!1},l.focus(),e||(window.addEventListener(`message`,d),f(),i?.())}}async getAuthData(t){let n=r(`${e}/auth/get`,{bot_id:t});return await(await fetch(n,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded; charset=UTF-8`,"X-Requested-With":`XMLHttpRequest`},credentials:`include`})).json()}openPopup(t,{width:n,height:i}){let a=Math.max(0,(screen.width-n)/2)+screen.availWidth,o=Math.max(0,(screen.height-i)/2)+screen.availHeight,s=r(`${e}/auth`,{bot_id:t,origin:location.origin||`${location.protocol}//${location.hostname}`,return_to:location.href});return window.open(s,`telegram_oauth_bot${t}`,`width=${n},height=${i},left=${a},top=${o},status=0,location=0,menubar=0,toolbar=0`)}};export{i as TelegramLoginClient,n as isAuthenticationError};
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["popup","data: {\n event: string\n result: false | TelegramUserData\n }","result: AuthResult"],"sources":["../src/consts.ts","../src/exceptions.ts","../src/utils.ts","../src/client.ts"],"sourcesContent":["export const POPUP_ORIGIN = 'https://oauth.telegram.org'\n","export class AuthenticationError extends Error {}\n\n/**\n * Function to check if an error is an instance of AuthenticationError.\n *\n * @param {unknown} error\n */\nexport function isAuthenticationError(\n error: unknown,\n): error is AuthenticationError {\n return error instanceof AuthenticationError\n}\n","export const buildUrl = (\n base: string,\n params: Record<string, boolean | number | string>,\n): string => {\n const searchParams = new URLSearchParams()\n\n for (const [key, value] of Object.entries(params)) {\n searchParams.append(key, value.toString())\n }\n\n return `${base}?${searchParams.toString()}`\n}\n","import { POPUP_ORIGIN } from './consts'\nimport { AuthenticationError } from './exceptions'\nimport { buildUrl } from './utils'\n\nexport interface PopupOptions {\n /**\n * Height of the popup\n */\n height: number\n /**\n * Width of the popup\n */\n width: number\n}\n\ninterface PopupInstance {\n authFinished: boolean\n window: Window\n}\n\ntype GetAuthResponse = (\n | { error: string }\n | { user: TelegramUserData }\n) & {\n html: string\n origin: string\n}\n\ntype AuthResult =\n | { data: null; error: Error }\n | { data: TelegramUserData; error: null }\n\n/**\n * Data returned after a successful Telegram login authentication.\n */\nexport interface TelegramUserData {\n /**\n * Unix timestamp indicating when the authentication occurred.\n */\n auth_date: number\n /**\n * User's first name.\n */\n first_name: string\n /**\n * Data hash for verification of the authentication data integrity.\n */\n hash: string\n /**\n * Unique identifier for the user.\n */\n id: number\n /**\n * User's last name, if available.\n */\n last_name?: string\n /**\n * URL of the user's profile photo, if available.\n */\n photo_url?: string\n /**\n * User's username, if available.\n */\n username?: string\n}\n\n/**\n * Configuration options for the Telegram login client.\n */\nexport interface TelegramLoginClientOptions {\n /**\n * Default popup window dimensions that will be used when no specific popup options are provided in the login method.\n * @default { width: 550, height: 470 }\n */\n defaultPopupOptions?: PopupOptions\n}\n\n/**\n * Configuration options for the Telegram login method.\n */\nexport interface LoginOptions {\n /**\n * The unique identifier of the Telegram bot. You can obtain it from the https://t.me/username_to_id_bot.\n */\n botId: number\n /**\n * Optional popup window configuration. If not provided, default popup options will be used.\n */\n popup?: Partial<PopupOptions>\n /**\n * Optional callback function that will be called if an error occurs during the login process.\n * @param {unknown} error - The error that occurred.\n */\n onError?: (error: unknown) => void\n /**\n * Optional callback function that will be called when the login process starts.\n */\n onStart?: () => void\n /**\n * Optional callback function that will be called when the login process completes successfully.\n * @param {TelegramUserData} data - The authentication data returned from Telegram.\n */\n onSuccess?: (data: TelegramUserData) => void\n}\n\n/**\n * Telegram login client.\n */\nexport class TelegramLoginClient {\n private defaultPopupOptions: PopupOptions\n private popups: Partial<Record<number, PopupInstance>> = {}\n\n /**\n * Create a new Telegram login client.\n * @param {TelegramLoginClientOptions} options - Configuration options for the Telegram login client.\n */\n constructor(options?: TelegramLoginClientOptions) {\n this.defaultPopupOptions = options?.defaultPopupOptions ?? {\n width: 550,\n height: 470,\n }\n }\n\n /**\n * Opens a popup window for the user to log in to Telegram.\n * @param {LoginOptions} options\n * @returns {void}\n */\n login(options: LoginOptions): void {\n const {\n botId,\n popup: popupOptions,\n onStart,\n onSuccess,\n onError,\n } = options\n\n const width =\n popupOptions?.width ?? this.defaultPopupOptions.width\n const height =\n popupOptions?.height ?? this.defaultPopupOptions.height\n\n const popup = this.openPopup(botId, { width, height })\n\n const handleAuth = ({ data, error }: AuthResult): void => {\n const popup = this.popups[botId]\n if (!popup || popup.authFinished) return\n popup.authFinished = true\n\n if (data) {\n onSuccess?.(data)\n } else {\n onError?.(error)\n }\n }\n\n const handleMessage = (event: MessageEvent<string>): void => {\n const popup = this.popups[botId]\n if (!popup) return\n if (event.source !== popup.window) return\n\n const data: {\n event: string\n result: false | TelegramUserData\n } = JSON.parse(event.data)\n\n if (data.event === 'auth_result') {\n const result = data.result\n ? { data: data.result, error: null }\n : { data: null, error: new AuthenticationError() }\n\n handleAuth(result)\n window.removeEventListener('message', handleMessage)\n }\n }\n\n const checkClose = async (): Promise<void> => {\n const popup = this.popups[botId]\n\n if (!popup || popup.authFinished) return\n if (!popup.window.closed) {\n setTimeout(checkClose, 100)\n return\n }\n\n let result: AuthResult\n\n try {\n const response = await this.getAuthData(botId)\n result =\n 'user' in response\n ? {\n data: response.user,\n error: null,\n }\n : {\n data: null,\n error: new AuthenticationError(response.error),\n }\n } catch (error) {\n // Casting error to Error type because it cannot be another type\n result = { data: null, error: error as Error }\n }\n\n handleAuth(result)\n window.removeEventListener('message', handleMessage)\n }\n\n if (popup) {\n const isPopupAlreadyExists =\n this.popups[botId]?.window.closed === false\n\n this.popups[botId] = { window: popup, authFinished: false }\n popup.focus()\n\n if (!isPopupAlreadyExists) {\n window.addEventListener('message', handleMessage)\n checkClose()\n onStart?.()\n }\n }\n }\n\n private async getAuthData(botId: number): Promise<GetAuthResponse> {\n const url = buildUrl(`${POPUP_ORIGIN}/auth/get`, {\n bot_id: botId,\n })\n const headers = {\n 'Content-Type':\n 'application/x-www-form-urlencoded; charset=UTF-8',\n 'X-Requested-With': 'XMLHttpRequest',\n }\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n credentials: 'include',\n })\n\n return await response.json()\n }\n\n private openPopup(\n botId: number,\n { width, height }: PopupOptions,\n ): WindowProxy | null {\n const left =\n Math.max(0, (screen.width - width) / 2) + screen.availWidth\n const top =\n Math.max(0, (screen.height - height) / 2) + screen.availHeight\n\n const popupUrl = buildUrl(`${POPUP_ORIGIN}/auth`, {\n bot_id: botId,\n origin:\n location.origin ||\n `${location.protocol}//${location.hostname}`,\n return_to: location.href,\n })\n\n return window.open(\n popupUrl,\n `telegram_oauth_bot${botId}`,\n `width=${width},height=${height},left=${left},top=${\n top\n },status=0,location=0,menubar=0,toolbar=0`,\n )\n }\n}\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@telegram-login-ultimate/core",
3
+ "version": "2.0.0",
4
+ "description": "Ultimate tool for working with Telegram Login API with TypeScript support",
5
+ "license": "MIT",
6
+ "author": {
7
+ "name": "notcodev",
8
+ "url": "https://github.com/notcodev"
9
+ },
10
+ "repository": {
11
+ "url": "https://github.com/notcodev/telegram-login-ultimate.git",
12
+ "type": "git"
13
+ },
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "files": [
18
+ "dist/**/*"
19
+ ],
20
+ "homepage": "https://github.com/notcodev/telegram-login-ultimate",
21
+ "bugs": "https://github.com/notcodev/telegram-login-ultimate/issues",
22
+ "main": "dist/index.js",
23
+ "module": "dist/index.mjs",
24
+ "types": "dist/index.d.ts",
25
+ "keywords": [
26
+ "telegram",
27
+ "login",
28
+ "widget",
29
+ "react"
30
+ ],
31
+ "scripts": {
32
+ "build": "tsdown",
33
+ "lint": "eslint . --ext ts --ext tsx --no-error-on-unmatched-pattern --fix"
34
+ }
35
+ }