@tma.js/init-data-node 1.4.0 → 2.0.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.
- package/LICENSE +1 -1
- package/README.md +9 -9
- package/dist/buf-converters.d.ts +13 -0
- package/dist/entries/node.cjs +80 -8
- package/dist/entries/node.cjs.map +1 -1
- package/dist/entries/node.d.ts +26 -12
- package/dist/entries/node.js +62 -10
- package/dist/entries/node.js.map +1 -1
- package/dist/entries/parsing-Cj_BXCnv.cjs +258 -0
- package/dist/entries/parsing-Cj_BXCnv.cjs.map +1 -0
- package/dist/entries/parsing-eczkSd-W.js +241 -0
- package/dist/entries/parsing-eczkSd-W.js.map +1 -0
- package/dist/entries/shared.d.ts +6 -4
- package/dist/entries/web.cjs +117 -21
- package/dist/entries/web.cjs.map +1 -1
- package/dist/entries/web.d.ts +33 -14
- package/dist/entries/web.js +97 -22
- package/dist/entries/web.js.map +1 -1
- package/dist/errors.d.ts +21 -0
- package/dist/hashToken.d.ts +2 -3
- package/dist/parsing.d.ts +58 -0
- package/dist/signDataFp.d.ts +13 -0
- package/dist/signFp.d.ts +35 -0
- package/dist/types.d.ts +2 -19
- package/dist/validation.d.ts +67 -0
- package/package.json +15 -9
- package/dist/entries/index-B-IiSE5b.js +0 -342
- package/dist/entries/index-B-IiSE5b.js.map +0 -1
- package/dist/entries/index-DQxFLF1J.cjs +0 -341
- package/dist/entries/index-DQxFLF1J.cjs.map +0 -1
- package/dist/initDataToSearchParams.d.ts +0 -3
- package/dist/sign.d.ts +0 -23
- package/dist/signData.d.ts +0 -21
- package/dist/validate.d.ts +0 -39
package/dist/entries/web.js
CHANGED
|
@@ -1,39 +1,114 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { BetterPromise } from "better-promises";
|
|
2
|
+
import * as E from "fp-ts/Either";
|
|
3
|
+
import * as TE from "fp-ts/TaskEither";
|
|
4
|
+
import { pipe } from "fp-ts/lib/function.js";
|
|
5
|
+
import { h as hashToken$1, A as AuthDateInvalidError, E as ExpiredError, S as SignatureInvalidError, c as SignatureMissingError, H as HexStringLengthInvalidError, s as signFp$1, a as signDataFp$1, v as validateFp$1 } from "./parsing-eczkSd-W.js";
|
|
6
|
+
import { i, e, p, d, f, g } from "./parsing-eczkSd-W.js";
|
|
7
|
+
import { deepSnakeToCamelObjKeys } from "@tma.js/toolkit";
|
|
3
8
|
const createHmac = async (data, key) => {
|
|
4
9
|
const encoder = new TextEncoder();
|
|
5
|
-
return
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
encoder.encode(data.toString())
|
|
16
|
-
)
|
|
10
|
+
return crypto.subtle.sign(
|
|
11
|
+
"HMAC",
|
|
12
|
+
await crypto.subtle.importKey(
|
|
13
|
+
"raw",
|
|
14
|
+
typeof key === "string" ? encoder.encode(key) : key,
|
|
15
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
16
|
+
false,
|
|
17
|
+
["sign", "verify"]
|
|
18
|
+
),
|
|
19
|
+
typeof data === "string" ? encoder.encode(data) : data
|
|
17
20
|
);
|
|
18
21
|
};
|
|
19
22
|
function hashToken(token) {
|
|
20
23
|
return hashToken$1(token, createHmac);
|
|
21
24
|
}
|
|
25
|
+
function isValidFp(value, token, options) {
|
|
26
|
+
return pipe(
|
|
27
|
+
validateFp(value, token, options),
|
|
28
|
+
TE.match(
|
|
29
|
+
(error) => {
|
|
30
|
+
return [
|
|
31
|
+
AuthDateInvalidError,
|
|
32
|
+
ExpiredError,
|
|
33
|
+
SignatureInvalidError,
|
|
34
|
+
SignatureMissingError,
|
|
35
|
+
HexStringLengthInvalidError
|
|
36
|
+
].some((errorClass) => errorClass.is(error)) ? E.right(false) : E.left(error);
|
|
37
|
+
},
|
|
38
|
+
() => E.right(true)
|
|
39
|
+
)
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
function isValid(value, token, options) {
|
|
43
|
+
return BetterPromise.fn(() => {
|
|
44
|
+
return pipe(
|
|
45
|
+
isValidFp(value, token, options),
|
|
46
|
+
TE.match((error) => {
|
|
47
|
+
throw error;
|
|
48
|
+
}, (isValid2) => isValid2)
|
|
49
|
+
)();
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function signFp(data, key, authDate, options) {
|
|
53
|
+
return signFp$1(data, key, authDate, signDataFp, options);
|
|
54
|
+
}
|
|
22
55
|
function sign(data, key, authDate, options) {
|
|
23
|
-
return
|
|
56
|
+
return BetterPromise.fn(() => {
|
|
57
|
+
return pipe(
|
|
58
|
+
signFp(data, key, authDate, options),
|
|
59
|
+
TE.match((e2) => {
|
|
60
|
+
throw e2;
|
|
61
|
+
}, (v) => v)
|
|
62
|
+
)();
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function signDataFp(data, key, options) {
|
|
66
|
+
return signDataFp$1(true, data, key, createHmac, options);
|
|
67
|
+
}
|
|
68
|
+
function signData(data, key, options) {
|
|
69
|
+
return BetterPromise.fn(() => {
|
|
70
|
+
return pipe(
|
|
71
|
+
signDataFp(data, key, options),
|
|
72
|
+
TE.match((e2) => {
|
|
73
|
+
throw e2;
|
|
74
|
+
}, (v) => v)
|
|
75
|
+
)();
|
|
76
|
+
});
|
|
24
77
|
}
|
|
25
|
-
|
|
26
|
-
return
|
|
78
|
+
function validateFp(value, token, options) {
|
|
79
|
+
return validateFp$1(true, value, token, signDataFp, options);
|
|
27
80
|
}
|
|
28
|
-
|
|
29
|
-
return
|
|
81
|
+
function validate(value, token, options) {
|
|
82
|
+
return BetterPromise.fn(async () => {
|
|
83
|
+
await pipe(
|
|
84
|
+
validateFp(value, token, options),
|
|
85
|
+
TE.mapLeft((error) => {
|
|
86
|
+
throw error;
|
|
87
|
+
})
|
|
88
|
+
)();
|
|
89
|
+
});
|
|
30
90
|
}
|
|
31
91
|
export {
|
|
92
|
+
AuthDateInvalidError,
|
|
93
|
+
ExpiredError,
|
|
94
|
+
HexStringLengthInvalidError,
|
|
95
|
+
SignatureInvalidError,
|
|
96
|
+
SignatureMissingError,
|
|
97
|
+
deepSnakeToCamelObjKeys,
|
|
32
98
|
hashToken,
|
|
33
|
-
|
|
34
|
-
|
|
99
|
+
isValid,
|
|
100
|
+
i as isValid3rd,
|
|
101
|
+
e as isValid3rdFp,
|
|
102
|
+
isValidFp,
|
|
103
|
+
p as parse,
|
|
104
|
+
d as parseFp,
|
|
35
105
|
sign,
|
|
36
106
|
signData,
|
|
37
|
-
|
|
107
|
+
signDataFp,
|
|
108
|
+
signFp,
|
|
109
|
+
validate,
|
|
110
|
+
f as validate3rd,
|
|
111
|
+
g as validate3rdFp,
|
|
112
|
+
validateFp
|
|
38
113
|
};
|
|
39
114
|
//# sourceMappingURL=web.js.map
|
package/dist/entries/web.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.js","sources":["../../src/entries/web.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"web.js","sources":["../../src/entries/web.ts"],"sourcesContent":["import { BetterPromise, type BetterPromiseRejectReason } from 'better-promises';\nimport * as E from 'fp-ts/Either';\nimport * as TE from 'fp-ts/TaskEither';\nimport { pipe } from 'fp-ts/lib/function.js';\n\nimport { hashToken as _hashToken } from '../hashToken.js';\nimport { signDataFp as _signDataFp, SignDataError, type SignDataOptions } from '../signDataFp.js';\nimport {\n signFp as _signFp,\n type SignableData,\n type SignOptions,\n} from '../signFp.js';\nimport type { CreateHmacFn, Text } from '../types.js';\nimport {\n validateFp as _validateFp,\n type ValidateValue,\n type ValidateAsyncError,\n type ValidateAsyncOptions,\n} from '../validation.js';\nimport {\n AuthDateInvalidError,\n ExpiredError,\n SignatureInvalidError,\n SignatureMissingError,\n HexStringLengthInvalidError,\n} from '../errors.js';\n\nconst createHmac: CreateHmacFn<true> = async (data, key) => {\n const encoder = new TextEncoder();\n\n return crypto.subtle.sign(\n 'HMAC',\n await crypto.subtle.importKey(\n 'raw',\n typeof key === 'string' ? encoder.encode(key) : key,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign', 'verify'],\n ),\n typeof data === 'string' ? encoder.encode(data) : data,\n );\n};\n\n/**\n * Hashes specified token using a string, expected during init data sign.\n * @param token - token to hash.\n */\nexport function hashToken(token: Text): Promise<ArrayBuffer> {\n return _hashToken(token, createHmac);\n}\n\n/**\n * @param value - value to check.\n * @param token - bot secret token.\n * @param options - additional validation options.\n * @returns True is specified init data is valid.\n */\nexport function isValidFp(\n value: ValidateValue,\n token: Text,\n options?: ValidateAsyncOptions,\n): TE.TaskEither<BetterPromiseRejectReason, boolean> {\n return pipe(\n validateFp(value, token, options),\n TE.match(\n error => {\n return [\n AuthDateInvalidError,\n ExpiredError,\n SignatureInvalidError,\n SignatureMissingError,\n HexStringLengthInvalidError,\n ].some(errorClass => errorClass.is(error))\n ? E.right(false)\n : E.left(error);\n },\n () => E.right(true),\n ),\n );\n}\n\n/**\n * @see isValidFp\n */\nexport function isValid(\n value: ValidateValue,\n token: Text,\n options?: ValidateAsyncOptions,\n): BetterPromise<boolean> {\n return BetterPromise.fn(() => {\n return pipe(\n isValidFp(value, token, options),\n TE.match(error => {\n throw error;\n }, isValid => isValid),\n )();\n });\n}\n\n/**\n * Signs specified init data.\n * @param data - init data to sign.\n * @param authDate - date, when this init data should be signed.\n * @param key - private key.\n * @param options - additional options.\n * @returns Signed init data presented as query parameters.\n */\nexport function signFp(\n data: SignableData,\n key: Text,\n authDate: Date,\n options?: SignOptions,\n): TE.TaskEither<SignDataError, string> {\n return _signFp(data, key, authDate, signDataFp, options);\n}\n\n/**\n * @see signFp\n */\nexport function sign(\n data: SignableData,\n key: Text,\n authDate: Date,\n options?: SignOptions,\n): BetterPromise<string> {\n return BetterPromise.fn(() => {\n return pipe(\n signFp(data, key, authDate, options),\n TE.match(e => {\n throw e;\n }, v => v),\n )();\n });\n}\n\n/**\n * Signs specified data with the passed token.\n * @param data - data to sign.\n * @param key - private key.\n * @param options - additional options.\n * @returns Data sign.\n */\nexport function signDataFp(\n data: Text,\n key: Text,\n options?: SignDataOptions,\n): TE.TaskEither<SignDataError, string> {\n return _signDataFp(true, data, key, createHmac, options);\n}\n\n/**\n * @see signDataFp\n */\nexport function signData(data: Text, key: Text, options?: SignDataOptions): BetterPromise<string> {\n return BetterPromise.fn(() => {\n return pipe(\n signDataFp(data, key, options),\n TE.match(e => {\n throw e;\n }, v => v),\n )();\n });\n}\n\n/**\n * Validates passed init data.\n * @param value - value to check.\n * @param token - bot secret token.\n * @param options - additional validation options.\n */\nexport function validateFp(\n value: ValidateValue,\n token: Text,\n options?: ValidateAsyncOptions,\n): TE.TaskEither<ValidateAsyncError, void> {\n return _validateFp(true, value, token, signDataFp, options);\n}\n\n/**\n * @see validateFp\n */\nexport function validate(\n value: ValidateValue,\n token: Text,\n options?: ValidateAsyncOptions,\n): BetterPromise<void> {\n return BetterPromise.fn(async () => {\n await pipe(\n validateFp(value, token, options),\n TE.mapLeft(error => {\n throw error;\n }),\n )();\n });\n}\n\nexport * from './shared.js';\n"],"names":["_hashToken","isValid","_signFp","e","_signDataFp","_validateFp"],"mappings":";;;;;;;AA2BA,MAAM,aAAiC,OAAO,MAAM,QAAQ;AACpD,QAAA,UAAU,IAAI,YAAY;AAEhC,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA,MAAM,OAAO,OAAO;AAAA,MAClB;AAAA,MACA,OAAO,QAAQ,WAAW,QAAQ,OAAO,GAAG,IAAI;AAAA,MAChD,EAAE,MAAM,QAAQ,MAAM,UAAU;AAAA,MAChC;AAAA,MACA,CAAC,QAAQ,QAAQ;AAAA,IACnB;AAAA,IACA,OAAO,SAAS,WAAW,QAAQ,OAAO,IAAI,IAAI;AAAA,EACpD;AACF;AAMO,SAAS,UAAU,OAAmC;AACpD,SAAAA,YAAW,OAAO,UAAU;AACrC;AAQgB,SAAA,UACd,OACA,OACA,SACmD;AAC5C,SAAA;AAAA,IACL,WAAW,OAAO,OAAO,OAAO;AAAA,IAChC,GAAG;AAAA,MACD,CAAS,UAAA;AACA,eAAA;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACA,EAAA,KAAK,CAAc,eAAA,WAAW,GAAG,KAAK,CAAC,IACrC,EAAE,MAAM,KAAK,IACb,EAAE,KAAK,KAAK;AAAA,MAClB;AAAA,MACA,MAAM,EAAE,MAAM,IAAI;AAAA,IAAA;AAAA,EAEtB;AACF;AAKgB,SAAA,QACd,OACA,OACA,SACwB;AACjB,SAAA,cAAc,GAAG,MAAM;AACrB,WAAA;AAAA,MACL,UAAU,OAAO,OAAO,OAAO;AAAA,MAC/B,GAAG,MAAM,CAAS,UAAA;AACV,cAAA;AAAA,MAAA,GACL,CAAAC,aAAWA,QAAO;AAAA,IAAA,EACrB;AAAA,EAAA,CACH;AACH;AAUO,SAAS,OACd,MACA,KACA,UACA,SACsC;AACtC,SAAOC,SAAQ,MAAM,KAAK,UAAU,YAAY,OAAO;AACzD;AAKO,SAAS,KACd,MACA,KACA,UACA,SACuB;AAChB,SAAA,cAAc,GAAG,MAAM;AACrB,WAAA;AAAA,MACL,OAAO,MAAM,KAAK,UAAU,OAAO;AAAA,MACnC,GAAG,MAAM,CAAKC,OAAA;AACN,cAAAA;AAAA,MAAA,GACL,OAAK,CAAC;AAAA,IAAA,EACT;AAAA,EAAA,CACH;AACH;AASgB,SAAA,WACd,MACA,KACA,SACsC;AACtC,SAAOC,aAAY,MAAM,MAAM,KAAK,YAAY,OAAO;AACzD;AAKgB,SAAA,SAAS,MAAY,KAAW,SAAkD;AACzF,SAAA,cAAc,GAAG,MAAM;AACrB,WAAA;AAAA,MACL,WAAW,MAAM,KAAK,OAAO;AAAA,MAC7B,GAAG,MAAM,CAAKD,OAAA;AACN,cAAAA;AAAA,MAAA,GACL,OAAK,CAAC;AAAA,IAAA,EACT;AAAA,EAAA,CACH;AACH;AAQgB,SAAA,WACd,OACA,OACA,SACyC;AACzC,SAAOE,aAAY,MAAM,OAAO,OAAO,YAAY,OAAO;AAC5D;AAKgB,SAAA,SACd,OACA,OACA,SACqB;AACd,SAAA,cAAc,GAAG,YAAY;AAC5B,UAAA;AAAA,MACJ,WAAW,OAAO,OAAO,OAAO;AAAA,MAChC,GAAG,QAAQ,CAAS,UAAA;AACZ,cAAA;AAAA,MACP,CAAA;AAAA,IAAA,EACD;AAAA,EAAA,CACH;AACH;"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
declare const AuthDateInvalidError_base: import('error-kid').ErrorClassWithData<[value?: string | undefined], {
|
|
2
|
+
value: string | undefined;
|
|
3
|
+
}>;
|
|
4
|
+
export declare class AuthDateInvalidError extends AuthDateInvalidError_base {
|
|
5
|
+
}
|
|
6
|
+
declare const SignatureInvalidError_base: import('error-kid').ErrorClass<[]>;
|
|
7
|
+
export declare class SignatureInvalidError extends SignatureInvalidError_base {
|
|
8
|
+
}
|
|
9
|
+
declare const HexStringLengthInvalidError_base: import('error-kid').ErrorClass<[]>;
|
|
10
|
+
export declare class HexStringLengthInvalidError extends HexStringLengthInvalidError_base {
|
|
11
|
+
}
|
|
12
|
+
declare const SignatureMissingError_base: import('error-kid').ErrorClass<[thirdParty: boolean]>;
|
|
13
|
+
export declare class SignatureMissingError extends SignatureMissingError_base {
|
|
14
|
+
}
|
|
15
|
+
declare const ExpiredError_base: import('error-kid').ErrorClassWithData<[issuedAt: Date, expiresAt: Date, now: Date], {
|
|
16
|
+
issuedAt: Date;
|
|
17
|
+
expiresAt: Date;
|
|
18
|
+
}>;
|
|
19
|
+
export declare class ExpiredError extends ExpiredError_base {
|
|
20
|
+
}
|
|
21
|
+
export {};
|
package/dist/hashToken.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import { CreateHmacFn } from './types.js';
|
|
2
|
-
|
|
3
|
-
export declare function hashToken<H extends CreateHmacFn<any>>(token: string | Buffer, createHmac: H): ReturnType<H>;
|
|
1
|
+
import { CreateHmacFn, Text } from './types.js';
|
|
2
|
+
export declare function hashToken<H extends CreateHmacFn<any>>(token: Text, createHmac: H): ReturnType<H>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { parseInitDataQueryFp, ParseInitDataQueryError } from '@tma.js/transformers';
|
|
2
|
+
/**
|
|
3
|
+
* Parses an incoming value as init data.
|
|
4
|
+
*/
|
|
5
|
+
export declare const parse: (value: string | URLSearchParams) => {
|
|
6
|
+
auth_date: Date;
|
|
7
|
+
can_send_after?: number | undefined;
|
|
8
|
+
chat?: ({
|
|
9
|
+
id: number;
|
|
10
|
+
photo_url?: string | undefined;
|
|
11
|
+
type: string;
|
|
12
|
+
title: string;
|
|
13
|
+
username?: string | undefined;
|
|
14
|
+
} & {
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}) | undefined;
|
|
17
|
+
chat_type?: string | undefined;
|
|
18
|
+
chat_instance?: string | undefined;
|
|
19
|
+
hash: string;
|
|
20
|
+
query_id?: string | undefined;
|
|
21
|
+
receiver?: ({
|
|
22
|
+
added_to_attachment_menu?: boolean | undefined;
|
|
23
|
+
allows_write_to_pm?: boolean | undefined;
|
|
24
|
+
first_name: string;
|
|
25
|
+
id: number;
|
|
26
|
+
is_bot?: boolean | undefined;
|
|
27
|
+
is_premium?: boolean | undefined;
|
|
28
|
+
last_name?: string | undefined;
|
|
29
|
+
language_code?: string | undefined;
|
|
30
|
+
photo_url?: string | undefined;
|
|
31
|
+
username?: string | undefined;
|
|
32
|
+
} & {
|
|
33
|
+
[key: string]: unknown;
|
|
34
|
+
}) | undefined;
|
|
35
|
+
start_param?: string | undefined;
|
|
36
|
+
signature: string;
|
|
37
|
+
user?: ({
|
|
38
|
+
added_to_attachment_menu?: boolean | undefined;
|
|
39
|
+
allows_write_to_pm?: boolean | undefined;
|
|
40
|
+
first_name: string;
|
|
41
|
+
id: number;
|
|
42
|
+
is_bot?: boolean | undefined;
|
|
43
|
+
is_premium?: boolean | undefined;
|
|
44
|
+
last_name?: string | undefined;
|
|
45
|
+
language_code?: string | undefined;
|
|
46
|
+
photo_url?: string | undefined;
|
|
47
|
+
username?: string | undefined;
|
|
48
|
+
} & {
|
|
49
|
+
[key: string]: unknown;
|
|
50
|
+
}) | undefined;
|
|
51
|
+
} & {
|
|
52
|
+
[key: string]: unknown;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Parses an incoming value as init data.
|
|
56
|
+
*/
|
|
57
|
+
export declare const parseFp: typeof parseInitDataQueryFp;
|
|
58
|
+
export { ParseInitDataQueryError as ParseError };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { hexToArrayBuffer } from './buf-converters.js';
|
|
2
|
+
import { CreateHmacFn, Text } from './types.js';
|
|
3
|
+
import * as E from 'fp-ts/Either';
|
|
4
|
+
import * as TE from 'fp-ts/TaskEither';
|
|
5
|
+
export interface SignDataOptions {
|
|
6
|
+
/**
|
|
7
|
+
* True, if token is already hashed and doesn't require hashing using HMAC-SHA-256.
|
|
8
|
+
*/
|
|
9
|
+
tokenHashed?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export type SignDataError = ReturnType<typeof hexToArrayBuffer> extends E.Either<infer U, any> ? U : never;
|
|
12
|
+
export declare function signDataFp(async: false, data: Text, key: Text, createHmac: CreateHmacFn<false>, options?: SignDataOptions): E.Either<SignDataError, string>;
|
|
13
|
+
export declare function signDataFp(async: true, data: Text, key: Text, createHmac: CreateHmacFn<true>, options?: SignDataOptions): TE.TaskEither<SignDataError, string>;
|
package/dist/signFp.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { InitDataLike } from '@tma.js/transformers';
|
|
2
|
+
import { Text } from './types.js';
|
|
3
|
+
import * as E from 'fp-ts/Either';
|
|
4
|
+
import * as TE from 'fp-ts/TaskEither';
|
|
5
|
+
export type SignableData = Omit<InitDataLike, 'auth_date' | 'hash' | 'signature'>;
|
|
6
|
+
export interface SignOptions {
|
|
7
|
+
/**
|
|
8
|
+
* True, if token is already hashed and doesn't require hashing using HMAC-SHA-256.
|
|
9
|
+
*/
|
|
10
|
+
tokenHashed?: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface SignDataFpArg<Async extends boolean, Left> {
|
|
13
|
+
(data: Text, key: Text, options?: SignOptions): Async extends true ? TE.TaskEither<Left, string> : E.Either<Left, string>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Signs specified init data.
|
|
17
|
+
* @param data - init data to sign.
|
|
18
|
+
* @param authDate - date, when this init data should be signed.
|
|
19
|
+
* @param key - private key.
|
|
20
|
+
* @param signData - function signing data.
|
|
21
|
+
* @param options - additional options.
|
|
22
|
+
* @returns Signed init data presented as query parameters.
|
|
23
|
+
*/
|
|
24
|
+
export declare function signFp<Left>(data: SignableData, key: Text, authDate: Date, signData: SignDataFpArg<false, Left>, options?: SignOptions): E.Either<Left, string>;
|
|
25
|
+
/**
|
|
26
|
+
* Signs specified init data.
|
|
27
|
+
* @param data - init data to sign.
|
|
28
|
+
* @param authDate - date, when this init data should be signed.
|
|
29
|
+
* @param key - private key.
|
|
30
|
+
* @param signData - function signing data.
|
|
31
|
+
* @param options - additional options.
|
|
32
|
+
* @returns Signed init data presented as query parameters.
|
|
33
|
+
*/
|
|
34
|
+
export declare function signFp<Left>(data: SignableData, key: Text, authDate: Date, signData: SignDataFpArg<true, Left>, options?: SignOptions): TE.TaskEither<Left, string>;
|
|
35
|
+
export {};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,24 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
import { SignDataOptions } from './signData.js';
|
|
3
|
-
|
|
4
|
-
export type Text = string | Buffer;
|
|
5
|
-
export type SignData = Omit<InitDataParsed, 'authDate' | 'hash'>;
|
|
6
|
-
export interface SignDataSyncFn {
|
|
7
|
-
(data: Text, key: Text, options?: SignDataOptions): string;
|
|
8
|
-
}
|
|
9
|
-
export interface SignDataAsyncFn {
|
|
10
|
-
(data: Text, key: Text, options?: SignDataOptions): Promise<string>;
|
|
11
|
-
}
|
|
1
|
+
export type Text = string | ArrayBuffer;
|
|
12
2
|
/**
|
|
13
3
|
* SHA-256 hashing function.
|
|
14
4
|
*/
|
|
15
5
|
export interface CreateHmacFn<Async extends boolean> {
|
|
16
|
-
(data: Text, key: Text): Async extends true ? Promise<
|
|
17
|
-
}
|
|
18
|
-
export interface SharedOptions {
|
|
19
|
-
/**
|
|
20
|
-
* True, if token is already hashed.
|
|
21
|
-
* @default false
|
|
22
|
-
*/
|
|
23
|
-
tokenHashed?: boolean;
|
|
6
|
+
(data: Text, key: Text): Async extends true ? Promise<ArrayBuffer> : ArrayBuffer;
|
|
24
7
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { BetterPromise, BetterPromiseOptions, BetterPromiseRejectReason } from 'better-promises';
|
|
2
|
+
import { AuthDateInvalidError, ExpiredError, SignatureInvalidError, SignatureMissingError } from './errors.js';
|
|
3
|
+
import { Text } from './types.js';
|
|
4
|
+
import * as E from 'fp-ts/Either';
|
|
5
|
+
import * as TE from 'fp-ts/TaskEither';
|
|
6
|
+
type OmittedPromiseOptions = Omit<BetterPromiseOptions, 'abortOnResolve' | 'abortOnReject'>;
|
|
7
|
+
export type ValidateValue = string | URLSearchParams;
|
|
8
|
+
export type Validate3rdValue = string | URLSearchParams;
|
|
9
|
+
export type ValidateError = SignatureMissingError | SignatureInvalidError | AuthDateInvalidError | ExpiredError;
|
|
10
|
+
export type ValidateAsyncError = ValidateError | BetterPromiseRejectReason;
|
|
11
|
+
export type Validate3rdError = SignatureMissingError | SignatureInvalidError | AuthDateInvalidError | ExpiredError | BetterPromiseRejectReason;
|
|
12
|
+
interface ValidateSignDataFpArg<Async extends boolean, Left> {
|
|
13
|
+
(data: Text, key: Text, options?: ValidateOptions): Async extends true ? TE.TaskEither<Left, string> : E.Either<Left, string>;
|
|
14
|
+
}
|
|
15
|
+
interface SharedValidateOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Time in seconds which states, how long from creation time init data is considered valid.
|
|
18
|
+
*
|
|
19
|
+
* In other words, in case when authDate + expiresIn is before current time, init data is
|
|
20
|
+
* recognized as expired.
|
|
21
|
+
*
|
|
22
|
+
* In case this value is equal to 0, the function does not check init data expiration.
|
|
23
|
+
* @default 86400 (1 day)
|
|
24
|
+
*/
|
|
25
|
+
expiresIn?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface ValidateOptions extends SharedValidateOptions {
|
|
28
|
+
/**
|
|
29
|
+
* True, if token is already hashed.
|
|
30
|
+
* @default false
|
|
31
|
+
*/
|
|
32
|
+
tokenHashed?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface ValidateAsyncOptions extends ValidateOptions, OmittedPromiseOptions {
|
|
35
|
+
}
|
|
36
|
+
export interface Validate3rdOptions extends SharedValidateOptions, OmittedPromiseOptions {
|
|
37
|
+
/**
|
|
38
|
+
* When true, uses the test environment public key to validate init data.
|
|
39
|
+
* @default false
|
|
40
|
+
*/
|
|
41
|
+
test?: boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Validates passed init data using a publicly known Ee25519 key.
|
|
45
|
+
* @param value - value to check.
|
|
46
|
+
* @param botId - bot identifier
|
|
47
|
+
* @param options - additional validation options.
|
|
48
|
+
*/
|
|
49
|
+
export declare function validate3rdFp(value: Validate3rdValue, botId: number, options?: Validate3rdOptions): TE.TaskEither<Validate3rdError, void>;
|
|
50
|
+
/**
|
|
51
|
+
* @see validate3rdFp
|
|
52
|
+
*/
|
|
53
|
+
export declare function validate3rd(value: Validate3rdValue, botId: number, options?: Validate3rdOptions): BetterPromise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* @param value - value to check.
|
|
56
|
+
* @param botId - bot identifier
|
|
57
|
+
* @param options - additional validation options.
|
|
58
|
+
* @returns True is specified init data is signed by Telegram.
|
|
59
|
+
*/
|
|
60
|
+
export declare function isValid3rdFp(value: Validate3rdValue, botId: number, options?: Validate3rdOptions): TE.TaskEither<void, boolean>;
|
|
61
|
+
/**
|
|
62
|
+
* @see isValid3rdFp
|
|
63
|
+
*/
|
|
64
|
+
export declare function isValid3rd(value: Validate3rdValue, botId: number, options?: Validate3rdOptions): BetterPromise<boolean>;
|
|
65
|
+
export declare function validateFp<Left>(async: false, value: ValidateValue, token: Text, signData: ValidateSignDataFpArg<false, Left>, options?: ValidateOptions): E.Either<Left | ValidateError, void>;
|
|
66
|
+
export declare function validateFp<Left>(async: true, value: ValidateValue, token: Text, signData: ValidateSignDataFpArg<true, Left>, options?: ValidateAsyncOptions): TE.TaskEither<Left | ValidateAsyncError, void>;
|
|
67
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tma.js/init-data-node",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "TypeScript Node library to operate with Telegram init data.",
|
|
5
5
|
"author": "Vladislav Kibenko <wolfram.deus@gmail.com>",
|
|
6
|
-
"homepage": "https://github.com/Telegram-Mini-Apps/
|
|
6
|
+
"homepage": "https://github.com/Telegram-Mini-Apps/telegram-apps#readme",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "git@github.com:Telegram-Mini-Apps/
|
|
10
|
-
"directory": "
|
|
9
|
+
"url": "git@github.com:Telegram-Mini-Apps/telegram-apps.git",
|
|
10
|
+
"directory": "tma.js/init-data-node"
|
|
11
11
|
},
|
|
12
12
|
"bugs": {
|
|
13
|
-
"url": "https://github.com/Telegram-Mini-Apps/
|
|
13
|
+
"url": "https://github.com/Telegram-Mini-Apps/telegram-apps/issues"
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
|
16
16
|
"telegram-mini-apps",
|
|
@@ -42,18 +42,24 @@
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@types/node": "^
|
|
46
|
-
"tsconfig": "0.0.2"
|
|
45
|
+
"@types/node": "^22.9.0",
|
|
46
|
+
"tsconfig": "0.0.2",
|
|
47
|
+
"test-utils": "0.0.1"
|
|
47
48
|
},
|
|
48
49
|
"publishConfig": {
|
|
49
50
|
"access": "public"
|
|
50
51
|
},
|
|
51
52
|
"dependencies": {
|
|
52
|
-
"
|
|
53
|
+
"better-promises": "^1.0.0",
|
|
54
|
+
"error-kid": "^1.0.2",
|
|
55
|
+
"fp-ts": "^2.16.11",
|
|
56
|
+
"@tma.js/types": "^1.0.0",
|
|
57
|
+
"@tma.js/transformers": "^1.0.1",
|
|
58
|
+
"@tma.js/toolkit": "^1.0.1"
|
|
53
59
|
},
|
|
54
60
|
"scripts": {
|
|
55
61
|
"test": "vitest --run",
|
|
56
|
-
"lint": "cd ../.. && eslint
|
|
62
|
+
"lint": "cd ../.. && eslint tma.js/init-data-node/src --ignore-pattern **/*.test.ts",
|
|
57
63
|
"lint:fix": "pnpm run lint --fix",
|
|
58
64
|
"typecheck": "tsc --noEmit",
|
|
59
65
|
"build:node": "vite build --ssr src/entries/node.ts",
|