@tma.js/init-data-node 1.1.16 → 1.2.1

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.
@@ -1,2 +1,5 @@
1
+ export { sign } from './sign.js';
2
+ export { signData } from './signData.js';
3
+ export type { SignData } from './types.js';
1
4
  export { validate, type ValidateOptions } from './validate.js';
2
5
  export { type Chat, type ChatType, type InitDataParsed, parseInitData as parse, type User, } from '@tma.js/sdk';
@@ -0,0 +1,4 @@
1
+ import { InitDataParsed } from '@tma.js/sdk';
2
+ import { URLSearchParams } from 'node:url';
3
+
4
+ export declare function initDataToSearchParams({ chat, receiver, user, ...data }: Partial<InitDataParsed>): URLSearchParams;
@@ -0,0 +1,10 @@
1
+ import { SignData } from './types.js';
2
+
3
+ /**
4
+ * Signs specified init data.
5
+ * @param data - init data to sign.
6
+ * @param authDate - date, when this init data should be signed.
7
+ * @param token - bot token.
8
+ * @returns Signed init data presented as query parameters.
9
+ */
10
+ export declare function sign(data: SignData, token: string, authDate: Date): string;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Signs specified data with the passed token.
3
+ * @param data - data to sign.
4
+ * @param token - bot token.
5
+ * @returns Data sign.
6
+ */
7
+ export declare function signData(data: string, token: string): string;
@@ -0,0 +1,4 @@
1
+ import { InitDataParsed } from '@tma.js/sdk';
2
+
3
+ export interface SignData extends Omit<InitDataParsed, 'authDate' | 'hash'> {
4
+ }
@@ -1,33 +1,26 @@
1
1
  import { URLSearchParams } from 'node:url';
2
+ import { InitData, InitDataParsed } from '@tma.js/sdk';
2
3
 
3
4
  export interface ValidateOptions {
4
5
  /**
5
- * Time in seconds which states, how long from creation time is init data
6
- * considered valid.
6
+ * Time in seconds which states, how long from creation time init data is considered valid.
7
7
  *
8
- * In other words, in case, when authDate + expiresIn is before current
9
- * time, init data recognized as expired.
8
+ * In other words, in case, when authDate + expiresIn is before current time, init data
9
+ * recognized as expired.
10
10
  *
11
- * In case, this value is equal to 0, function does not check init data
12
- * expiration.
11
+ * In case, this value is equal to 0, function does not check init data expiration.
13
12
  * @default 86400 (1 day)
14
13
  */
15
14
  expiresIn?: number;
16
15
  }
17
16
  /**
18
- * Validates passed init data presented as search params converted to string,
19
- * or its object presentation.
20
- *
21
- * @param sp - search parameters.
22
- * @param token - Telegram bot secret token.
23
- * @param options - validation options.
24
- * @see toSearchParams
25
- * @throws {TypeError} "hash" should be string.
26
- * @throws {Error} "hash" is empty or not found.
27
- * @throws {TypeError} "auth_date" should be string.
28
- * @throws {TypeError} "auth_date" does not represent integer.
29
- * @throws {Error} "auth_date" is empty or not found.
30
- * @throws {Error} Init data expired.
31
- * @throws {Error} Sign invalid.
17
+ * Validates passed init data.
18
+ * @param value - value to check.
19
+ * @param token - bot secret token.
20
+ * @param options - additional validation options.
21
+ * @throws {TypeError} "auth_date" should present integer
22
+ * @throws {Error} "hash" is empty or not found
23
+ * @throws {Error} "auth_date" is empty or not found
24
+ * @throws {Error} Init data expired
32
25
  */
33
- export declare function validate(sp: string | URLSearchParams, token: string, options?: ValidateOptions): void;
26
+ export declare function validate(value: InitData | InitDataParsed | string | URLSearchParams, token: string, options?: ValidateOptions): void;
package/dist/index.cjs CHANGED
@@ -1,3 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=require("node:crypto"),D=require("node:url");function N(t,e,r={}){const a=typeof t=="string"?new D.URLSearchParams(t):t;let n=new Date(0),i="";const u=[];if(a.forEach((d,m)=>{if(m==="hash"){i=d;return}if(m==="auth_date"){const g=parseInt(d,10);if(Number.isNaN(g))throw new TypeError('"auth_date" should present integer');n=new Date(g*1e3)}u.push(`${m}=${d}`)}),i.length===0)throw new Error('"hash" is empty or not found');if(n.getTime()===0)throw new Error('"auth_date" is empty or not found');const{expiresIn:s=86400}=r;if(s>0&&n.getTime()+s*1e3<new Date().getTime())throw new Error("Init data expired");if(u.sort(),b.createHmac("sha256",b.createHmac("sha256","WebAppData").update(e).digest()).update(u.join(`
2
- `)).digest().toString("hex")!==i)throw new Error("Signature is invalid")}class y extends Error{constructor(e,r,a){super(r,{cause:a}),this.type=e,Object.setPrototypeOf(this,y.prototype)}}function _(t,e,r){return new y(t,e,r)}const T="ERR_UNEXPECTED_TYPE",v="ERR_PARSE";function l(){return _(T,"Value has unexpected type")}class w{constructor(e,r,a){this.parser=e,this.isOptional=r,this.type=a}parse(e){if(!(this.isOptional&&e===void 0))try{return this.parser(e)}catch(r){throw _(v,`Unable to parse value${this.type?` as ${this.type}`:""}`,r)}}optional(){return this.isOptional=!0,this}}function h(t,e){return()=>new w(t,!1,e)}const c=h(t=>{if(typeof t=="boolean")return t;const e=String(t);if(e==="1"||e==="true")return!0;if(e==="0"||e==="false")return!1;throw l()},"boolean");function S(t,e){const r={};for(const a in t){const n=t[a];if(!n)continue;let i,u;if(typeof n=="function"||"parse"in n)i=a,u=typeof n=="function"?n:n.parse.bind(n);else{const{type:s}=n;i=n.from||a,u=typeof s=="function"?s:s.parse.bind(s)}try{const s=u(e(i));s!==void 0&&(r[a]=s)}catch(s){throw _(v,`Unable to parse field "${a}"`,s)}}return r}function P(t){let e=t;if(typeof e=="string"&&(e=JSON.parse(e)),typeof e!="object"||e===null||Array.isArray(e))throw l();return e}function p(t,e){return new w(r=>{const a=P(r);return S(t,n=>a[n])},!1,e)}const f=h(t=>{if(typeof t=="number")return t;if(typeof t=="string"){const e=Number(t);if(!Number.isNaN(e))return e}throw l()},"number");function $(t){return/^#[\da-f]{6}$/i.test(t)}function q(t){return/^#[\da-f]{3}$/i.test(t)}function R(t){const e=t.replace(/\s/g,"").toLowerCase();if($(e))return e;if(q(e)){let a="#";for(let n=0;n<3;n+=1)a+=e[1+n].repeat(2);return a}const r=e.match(/^rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)$/)||e.match(/^rgba\((\d{1,3}),(\d{1,3}),(\d{1,3}),\d{1,3}\)$/);if(!r)throw new Error(`Value "${t}" does not satisfy any of known RGB formats.`);return r.slice(1).reduce((a,n)=>{const i=parseInt(n,10).toString(16);return a+(i.length===1?"0":"")+i},"#")}const o=h(t=>{if(typeof t=="string"||typeof t=="number")return t.toString();throw l()},"string"),U=h(t=>R(o().parse(t)),"rgb"),x=p({button_id:t=>t==null?void 0:o().parse(t)});p({req_id:o(),data:t=>t===null?t:o().optional().parse(t)}),p({req_id:o(),result:t=>t,error:o().optional()}),p({slug:o(),status:o()}),p({status:o()}),p({data:o().optional()}),p({theme_params:t=>{const e=U().optional();return Object.entries(P(t)).reduce((r,[a,n])=>(r[a]=e.parse(n),r),{})}}),p({height:f(),width:t=>t==null?window.innerWidth:f().parse(t),is_state_stable:c(),is_expanded:c()}),p({status:o()});const O=h(t=>t instanceof Date?t:new Date(f().parse(t)*1e3),"Date");function I(t,e){return new w(r=>{if(typeof r!="string"&&!(r instanceof URLSearchParams))throw l();const a=typeof r=="string"?new URLSearchParams(r):r;return S(t,n=>{const i=a.get(n);return i===null?void 0:i})},!1,e)}const A=p({id:f(),type:o(),title:o(),photoUrl:{type:o().optional(),from:"photo_url"},username:o().optional()},"Chat").optional(),E=p({addedToAttachmentMenu:{type:c().optional(),from:"added_to_attachment_menu"},allowsWriteToPm:{type:c().optional(),from:"allows_write_to_pm"},firstName:{type:o(),from:"first_name"},id:f(),isBot:{type:c().optional(),from:"is_bot"},isPremium:{type:c().optional(),from:"is_premium"},languageCode:{type:o().optional(),from:"language_code"},lastName:{type:o().optional(),from:"last_name"},photoUrl:{type:o().optional(),from:"photo_url"},username:o().optional()},"User").optional();function j(){return I({authDate:{type:O(),from:"auth_date"},canSendAfter:{type:f().optional(),from:"can_send_after"},chat:A,chatInstance:{type:o().optional(),from:"chat_instance"},chatType:{type:o().optional(),from:"chat_type"},hash:o(),queryId:{type:o().optional(),from:"query_id"},receiver:E,startParam:{type:o().optional(),from:"start_param"},user:E},"InitData")}function C(t){return j().parse(t)}exports.parse=C;exports.validate=N;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const S=require("node:crypto"),m=require("node:url");function _(t,e){return S.createHmac("sha256",S.createHmac("sha256","WebAppData").update(e).digest()).update(t).digest().toString("hex")}function $(t){const e={};for(const n in t){const r=t[n];r!==void 0&&(e[n]=r)}return e}function v(t){return t?JSON.stringify({added_to_attachment_menu:t.addedToAttachmentMenu,allows_write_to_pm:t.allowsWriteToPm,first_name:t.firstName,id:t.id,is_bot:t.isBot,is_premium:t.isPremium,language_code:t.languageCode,last_name:t.lastName,photo_url:t.photoUrl,username:t.username}):void 0}function D({chat:t,receiver:e,user:n,...r}){var o;return new m.URLSearchParams($({auth_date:r.authDate?(+r.authDate/1e3|0).toString():void 0,can_send_after:(o=r.canSendAfter)==null?void 0:o.toString(),chat:t?JSON.stringify({id:t.id,type:t.type,title:t.title,photo_url:t.type,username:t.username}):void 0,chat_instance:r.chatInstance,chat_type:r.chatType||void 0,hash:r.hash,query_id:r.queryId,receiver:v(e),start_param:r.startParam||void 0,user:v(n)}))}function q(t,e,n){const r=D({...t,authDate:n}),o=[...r.entries()].map(([i,u])=>`${i}=${u}`).sort();return r.append("hash",_(o.join(`
2
+ `),e)),r.toString()}function R(t,e,n={}){let r,o;const i=[];if(new m.URLSearchParams(typeof t=="string"||t instanceof m.URLSearchParams?t:D(t)).forEach((s,l)=>{if(l==="hash"){o=s;return}if(l==="auth_date"){const b=parseInt(s,10);if(Number.isNaN(b))throw new TypeError('"auth_date" should present integer');r=new Date(b*1e3)}i.push(`${l}=${s}`)}),!o)throw new Error('"hash" is empty or not found');if(!r)throw new Error('"auth_date" is empty or not found');const{expiresIn:u=86400}=n;if(u>0&&+r+u*1e3<Date.now())throw new Error("Init data expired");if(i.sort(),_(i.join(`
3
+ `),e)!==o)throw new Error("Signature is invalid")}class y extends Error{constructor(e,n,r){super(n,{cause:r}),this.type=e,Object.setPrototypeOf(this,y.prototype)}}function g(t,e,n){return new y(t,e,n)}const T="ERR_UNEXPECTED_TYPE",E="ERR_PARSE";function d(){return g(T,"Value has unexpected type")}class w{constructor(e,n,r){this.parser=e,this.isOptional=n,this.type=r}parse(e){if(!(this.isOptional&&e===void 0))try{return this.parser(e)}catch(n){throw g(E,`Unable to parse value${this.type?` as ${this.type}`:""}`,n)}}optional(){return this.isOptional=!0,this}}function h(t,e){return()=>new w(t,!1,e)}const c=h(t=>{if(typeof t=="boolean")return t;const e=String(t);if(e==="1"||e==="true")return!0;if(e==="0"||e==="false")return!1;throw d()},"boolean");function N(t,e){const n={};for(const r in t){const o=t[r];if(!o)continue;let i,u;if(typeof o=="function"||"parse"in o)i=r,u=typeof o=="function"?o:o.parse.bind(o);else{const{type:s}=o;i=o.from||r,u=typeof s=="function"?s:s.parse.bind(s)}try{const s=u(e(i));s!==void 0&&(n[r]=s)}catch(s){throw g(E,`Unable to parse field "${r}"`,s)}}return n}function U(t){let e=t;if(typeof e=="string"&&(e=JSON.parse(e)),typeof e!="object"||e===null||Array.isArray(e))throw d();return e}function p(t,e){return new w(n=>{const r=U(n);return N(t,o=>r[o])},!1,e)}const f=h(t=>{if(typeof t=="number")return t;if(typeof t=="string"){const e=Number(t);if(!Number.isNaN(e))return e}throw d()},"number");function O(t){return/^#[\da-f]{6}$/i.test(t)}function I(t){return/^#[\da-f]{3}$/i.test(t)}function x(t){const e=t.replace(/\s/g,"").toLowerCase();if(O(e))return e;if(I(e)){let r="#";for(let o=0;o<3;o+=1)r+=e[1+o].repeat(2);return r}const n=e.match(/^rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)$/)||e.match(/^rgba\((\d{1,3}),(\d{1,3}),(\d{1,3}),\d{1,3}\)$/);if(!n)throw new Error(`Value "${t}" does not satisfy any of known RGB formats.`);return n.slice(1).reduce((r,o)=>{const i=parseInt(o,10).toString(16);return r+(i.length===1?"0":"")+i},"#")}const a=h(t=>{if(typeof t=="string"||typeof t=="number")return t.toString();throw d()},"string"),A=h(t=>x(a().parse(t)),"rgb"),L=p({button_id:t=>t==null?void 0:a().parse(t)});p({req_id:a(),data:t=>t===null?t:a().optional().parse(t)}),p({req_id:a(),result:t=>t,error:a().optional()}),p({slug:a(),status:a()}),p({status:a()}),p({data:a().optional()}),p({theme_params:t=>{const e=A().optional();return Object.entries(U(t)).reduce((n,[r,o])=>(n[r]=e.parse(o),n),{})}}),p({height:f(),width:t=>t==null?window.innerWidth:f().parse(t),is_state_stable:c(),is_expanded:c()}),p({status:a()});const j=h(t=>t instanceof Date?t:new Date(f().parse(t)*1e3),"Date");function C(t,e){return new w(n=>{if(typeof n!="string"&&!(n instanceof URLSearchParams))throw d();const r=typeof n=="string"?new URLSearchParams(n):n;return N(t,o=>{const i=r.get(o);return i===null?void 0:i})},!1,e)}const J=p({id:f(),type:a(),title:a(),photoUrl:{type:a().optional(),from:"photo_url"},username:a().optional()},"Chat").optional(),P=p({addedToAttachmentMenu:{type:c().optional(),from:"added_to_attachment_menu"},allowsWriteToPm:{type:c().optional(),from:"allows_write_to_pm"},firstName:{type:a(),from:"first_name"},id:f(),isBot:{type:c().optional(),from:"is_bot"},isPremium:{type:c().optional(),from:"is_premium"},languageCode:{type:a().optional(),from:"language_code"},lastName:{type:a().optional(),from:"last_name"},photoUrl:{type:a().optional(),from:"photo_url"},username:a().optional()},"User").optional();function M(){return C({authDate:{type:j(),from:"auth_date"},canSendAfter:{type:f().optional(),from:"can_send_after"},chat:J,chatInstance:{type:a().optional(),from:"chat_instance"},chatType:{type:a().optional(),from:"chat_type"},hash:a(),queryId:{type:a().optional(),from:"query_id"},receiver:P,startParam:{type:a().optional(),from:"start_param"},user:P},"InitData")}function W(t){return M().parse(t)}exports.parse=W;exports.sign=q;exports.signData=_;exports.validate=R;
3
4
  //# sourceMappingURL=index.cjs.map