@tma.js/init-data-node 2.0.5 → 2.0.7

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,5 +1,5 @@
1
+ import { either as E } from 'fp-ts';
1
2
  import { HexStringLengthInvalidError } from './errors.js';
2
- import * as E from 'fp-ts/Either';
3
3
  /**
4
4
  * Converts a hex string to ArrayBuffer.
5
5
  * @param hexString - value to convert.
@@ -1,27 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const E = require("fp-ts/Either");
4
- const function_js = require("fp-ts/lib/function.js");
3
+ const fpTs = require("fp-ts");
5
4
  const node_crypto = require("node:crypto");
6
- const parsing = require("./parsing-pEQ1lsuE.cjs");
5
+ const parsing = require("./parsing-BMJa8cb6.cjs");
7
6
  const toolkit = require("@tma.js/toolkit");
8
- function _interopNamespaceDefault(e) {
9
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
10
- if (e) {
11
- for (const k in e) {
12
- if (k !== "default") {
13
- const d = Object.getOwnPropertyDescriptor(e, k);
14
- Object.defineProperty(n, k, d.get ? d : {
15
- enumerable: true,
16
- get: () => e[k]
17
- });
18
- }
19
- }
20
- }
21
- n.default = e;
22
- return Object.freeze(n);
23
- }
24
- const E__namespace = /* @__PURE__ */ _interopNamespaceDefault(E);
25
7
  function textToBuffer(text) {
26
8
  return Buffer.from(typeof text === "string" ? text : new Uint8Array(text));
27
9
  }
@@ -34,18 +16,18 @@ function hashToken(token) {
34
16
  return Buffer.from(parsing.hashToken(token, createHmac));
35
17
  }
36
18
  function isValid(value, token, options) {
37
- return function_js.pipe(
19
+ return fpTs.function.pipe(
38
20
  validateFp(value, token, options),
39
- E__namespace.match(() => false, () => true)
21
+ fpTs.either.match(() => false, () => true)
40
22
  );
41
23
  }
42
24
  function signFp(data, key, authDate, options) {
43
25
  return parsing.signFp(data, key, authDate, signDataFp, options);
44
26
  }
45
27
  function sign(data, key, authDate, options) {
46
- return function_js.pipe(
28
+ return fpTs.function.pipe(
47
29
  signFp(data, key, authDate, options),
48
- E__namespace.match((e) => {
30
+ fpTs.either.match((e) => {
49
31
  throw e;
50
32
  }, (v) => v)
51
33
  );
@@ -54,9 +36,9 @@ function signDataFp(data, key, options) {
54
36
  return parsing.signDataFp(false, data, key, createHmac, options);
55
37
  }
56
38
  function signData(data, key, options) {
57
- return function_js.pipe(
39
+ return fpTs.function.pipe(
58
40
  signDataFp(data, key, options),
59
- E__namespace.match((e) => {
41
+ fpTs.either.match((e) => {
60
42
  throw e;
61
43
  }, (v) => v)
62
44
  );
@@ -65,9 +47,9 @@ function validateFp(value, token, options) {
65
47
  return parsing.validateFp(false, value, token, signDataFp, options);
66
48
  }
67
49
  function validate(value, token, options) {
68
- function_js.pipe(
50
+ fpTs.function.pipe(
69
51
  validateFp(value, token, options),
70
- E__namespace.mapLeft((error) => {
52
+ fpTs.either.mapLeft((error) => {
71
53
  throw error;
72
54
  })
73
55
  );
@@ -1 +1 @@
1
- {"version":3,"file":"node.cjs","sources":["../../src/entries/node.ts"],"sourcesContent":["import * as E from 'fp-ts/Either';\nimport { pipe } from 'fp-ts/lib/function.js';\nimport { createHmac as nodeCreateHmac } from 'node:crypto';\n\nimport { bufferToArrayBuffer } from '../buf-converters.js';\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 ValidateError,\n type ValidateOptions,\n type ValidateValue,\n} from '../validation.js';\n\n/**\n * Converts Text to Node.js Buffer.\n * @param text - text to convert\n */\nfunction textToBuffer(text: Text): Buffer {\n return Buffer.from(typeof text === 'string' ? text : new Uint8Array(text));\n}\n\nconst createHmac: CreateHmacFn<false> = (data, key) => {\n return bufferToArrayBuffer(\n nodeCreateHmac('sha256', textToBuffer(key))\n .update(textToBuffer(data))\n .digest(),\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): Buffer {\n return Buffer.from(_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 isValid(value: ValidateValue, token: Text, options?: ValidateOptions): boolean {\n return pipe(\n validateFp(value, token, options),\n E.match(() => false, () => true),\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): E.Either<SignDataError, string> {\n return _signFp(data, key, authDate, signDataFp, options);\n}\n\n/**\n * @see signFp\n */\nexport function sign(data: SignableData, key: Text, authDate: Date, options?: SignOptions): string {\n return pipe(\n signFp(data, key, authDate, options),\n E.match(e => {\n throw e;\n }, v => v),\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): E.Either<SignDataError, string> {\n return _signDataFp(false, data, key, createHmac, options);\n}\n\n/**\n * @see signDataFp\n */\nexport function signData(data: Text, key: Text, options?: SignDataOptions): string {\n return pipe(\n signDataFp(data, key, options),\n E.match(e => {\n throw e;\n }, v => v),\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?: ValidateOptions,\n): E.Either<ValidateError, void> {\n return _validateFp(false, value, token, signDataFp, options);\n}\n\n/**\n * @see validateFp\n */\nexport function validate(value: ValidateValue, token: Text, options?: ValidateOptions): void {\n pipe(\n validateFp(value, token, options),\n E.mapLeft(error => {\n throw error;\n }),\n );\n}\n\nexport * from './shared.js';\n"],"names":["bufferToArrayBuffer","nodeCreateHmac","_hashToken","pipe","E","_signFp","_signDataFp","_validateFp"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAS,aAAa,MAAoB;AACjC,SAAA,OAAO,KAAK,OAAO,SAAS,WAAW,OAAO,IAAI,WAAW,IAAI,CAAC;AAC3E;AAEA,MAAM,aAAkC,CAAC,MAAM,QAAQ;AAC9C,SAAAA,QAAA;AAAA,IACLC,uBAAe,UAAU,aAAa,GAAG,CAAC,EACvC,OAAO,aAAa,IAAI,CAAC,EACzB,OAAO;AAAA,EACZ;AACF;AAMO,SAAS,UAAU,OAAqB;AAC7C,SAAO,OAAO,KAAKC,QAAW,UAAA,OAAO,UAAU,CAAC;AAClD;AAQgB,SAAA,QAAQ,OAAsB,OAAa,SAAoC;AACtF,SAAAC,YAAA;AAAA,IACL,WAAW,OAAO,OAAO,OAAO;AAAA,IAChCC,aAAE,MAAM,MAAM,OAAO,MAAM,IAAI;AAAA,EACjC;AACF;AAUO,SAAS,OACd,MACA,KACA,UACA,SACiC;AACjC,SAAOC,QAAAA,OAAQ,MAAM,KAAK,UAAU,YAAY,OAAO;AACzD;AAKO,SAAS,KAAK,MAAoB,KAAW,UAAgB,SAA+B;AAC1F,SAAAF,YAAA;AAAA,IACL,OAAO,MAAM,KAAK,UAAU,OAAO;AAAA,IACnCC,aAAE,MAAM,CAAK,MAAA;AACL,YAAA;AAAA,IAAA,GACL,OAAK,CAAC;AAAA,EACX;AACF;AASgB,SAAA,WACd,MACA,KACA,SACiC;AACjC,SAAOE,QAAAA,WAAY,OAAO,MAAM,KAAK,YAAY,OAAO;AAC1D;AAKgB,SAAA,SAAS,MAAY,KAAW,SAAmC;AAC1E,SAAAH,YAAA;AAAA,IACL,WAAW,MAAM,KAAK,OAAO;AAAA,IAC7BC,aAAE,MAAM,CAAK,MAAA;AACL,YAAA;AAAA,IAAA,GACL,OAAK,CAAC;AAAA,EACX;AACF;AAQgB,SAAA,WACd,OACA,OACA,SAC+B;AAC/B,SAAOG,QAAAA,WAAY,OAAO,OAAO,OAAO,YAAY,OAAO;AAC7D;AAKgB,SAAA,SAAS,OAAsB,OAAa,SAAiC;AAC3FJ,cAAA;AAAA,IACE,WAAW,OAAO,OAAO,OAAO;AAAA,IAChCC,aAAE,QAAQ,CAAS,UAAA;AACX,YAAA;AAAA,IACP,CAAA;AAAA,EACH;AACF;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"node.cjs","sources":["../../src/entries/node.ts"],"sourcesContent":["import { either as E, function as fn } from 'fp-ts';\nimport { createHmac as nodeCreateHmac } from 'node:crypto';\n\nimport { bufferToArrayBuffer } from '../buf-converters.js';\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 ValidateError,\n type ValidateOptions,\n type ValidateValue,\n} from '../validation.js';\n\n/**\n * Converts Text to NodE.js Buffer.\n * @param text - text to convert\n */\nfunction textToBuffer(text: Text): Buffer {\n return Buffer.from(typeof text === 'string' ? text : new Uint8Array(text));\n}\n\nconst createHmac: CreateHmacFn<false> = (data, key) => {\n return bufferToArrayBuffer(\n nodeCreateHmac('sha256', textToBuffer(key))\n .update(textToBuffer(data))\n .digest(),\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): Buffer {\n return Buffer.from(_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 isValid(value: ValidateValue, token: Text, options?: ValidateOptions): boolean {\n return fn.pipe(\n validateFp(value, token, options),\n E.match(() => false, () => true),\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): E.Either<SignDataError, string> {\n return _signFp(data, key, authDate, signDataFp, options);\n}\n\n/**\n * @see signFp\n */\nexport function sign(data: SignableData, key: Text, authDate: Date, options?: SignOptions): string {\n return fn.pipe(\n signFp(data, key, authDate, options),\n E.match(e => {\n throw e;\n }, v => v),\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): E.Either<SignDataError, string> {\n return _signDataFp(false, data, key, createHmac, options);\n}\n\n/**\n * @see signDataFp\n */\nexport function signData(data: Text, key: Text, options?: SignDataOptions): string {\n return fn.pipe(\n signDataFp(data, key, options),\n E.match(e => {\n throw e;\n }, v => v),\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?: ValidateOptions,\n): E.Either<ValidateError, void> {\n return _validateFp(false, value, token, signDataFp, options);\n}\n\n/**\n * @see validateFp\n */\nexport function validate(value: ValidateValue, token: Text, options?: ValidateOptions): void {\n fn.pipe(\n validateFp(value, token, options),\n E.mapLeft(error => {\n throw error;\n }),\n );\n}\n\nexport * from './shared.js';\n"],"names":["bufferToArrayBuffer","nodeCreateHmac","_hashToken","fn","E","_signFp","_signDataFp","_validateFp"],"mappings":";;;;;;AAuBA,SAAS,aAAa,MAAoB;AACjC,SAAA,OAAO,KAAK,OAAO,SAAS,WAAW,OAAO,IAAI,WAAW,IAAI,CAAC;AAC3E;AAEA,MAAM,aAAkC,CAAC,MAAM,QAAQ;AAC9C,SAAAA,QAAA;AAAA,IACLC,uBAAe,UAAU,aAAa,GAAG,CAAC,EACvC,OAAO,aAAa,IAAI,CAAC,EACzB,OAAO;AAAA,EACZ;AACF;AAMO,SAAS,UAAU,OAAqB;AAC7C,SAAO,OAAO,KAAKC,QAAW,UAAA,OAAO,UAAU,CAAC;AAClD;AAQgB,SAAA,QAAQ,OAAsB,OAAa,SAAoC;AAC7F,SAAOC,KAAG,SAAA;AAAA,IACR,WAAW,OAAO,OAAO,OAAO;AAAA,IAChCC,KAAAA,OAAE,MAAM,MAAM,OAAO,MAAM,IAAI;AAAA,EACjC;AACF;AAUO,SAAS,OACd,MACA,KACA,UACA,SACiC;AACjC,SAAOC,QAAAA,OAAQ,MAAM,KAAK,UAAU,YAAY,OAAO;AACzD;AAKO,SAAS,KAAK,MAAoB,KAAW,UAAgB,SAA+B;AACjG,SAAOF,KAAG,SAAA;AAAA,IACR,OAAO,MAAM,KAAK,UAAU,OAAO;AAAA,IACnCC,YAAE,MAAM,CAAK,MAAA;AACL,YAAA;AAAA,IAAA,GACL,OAAK,CAAC;AAAA,EACX;AACF;AASgB,SAAA,WACd,MACA,KACA,SACiC;AACjC,SAAOE,QAAAA,WAAY,OAAO,MAAM,KAAK,YAAY,OAAO;AAC1D;AAKgB,SAAA,SAAS,MAAY,KAAW,SAAmC;AACjF,SAAOH,KAAG,SAAA;AAAA,IACR,WAAW,MAAM,KAAK,OAAO;AAAA,IAC7BC,YAAE,MAAM,CAAK,MAAA;AACL,YAAA;AAAA,IAAA,GACL,OAAK,CAAC;AAAA,EACX;AACF;AAQgB,SAAA,WACd,OACA,OACA,SAC+B;AAC/B,SAAOG,QAAAA,WAAY,OAAO,OAAO,OAAO,YAAY,OAAO;AAC7D;AAKgB,SAAA,SAAS,OAAsB,OAAa,SAAiC;AACxFJ,OAAAA,SAAA;AAAA,IACD,WAAW,OAAO,OAAO,OAAO;AAAA,IAChCC,YAAE,QAAQ,CAAS,UAAA;AACX,YAAA;AAAA,IACP,CAAA;AAAA,EACH;AACF;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,8 +1,8 @@
1
+ import { either as E } from 'fp-ts';
1
2
  import { SignDataError, SignDataOptions } from '../signDataFp.js';
2
3
  import { SignableData, SignOptions } from '../signFp.js';
3
4
  import { Text } from '../types.js';
4
5
  import { ValidateError, ValidateOptions, ValidateValue } from '../validation.js';
5
- import * as E from 'fp-ts/Either';
6
6
  /**
7
7
  * Hashes specified token using a string, expected during init data sign.
8
8
  * @param token - token to hash.
@@ -1,8 +1,7 @@
1
- import * as E from "fp-ts/Either";
2
- import { pipe } from "fp-ts/lib/function.js";
1
+ import { function as _function, either } from "fp-ts";
3
2
  import { createHmac as createHmac$1 } from "node:crypto";
4
- import { h as hashToken$1, s as signFp$1, a as signDataFp$1, v as validateFp$1, b as bufferToArrayBuffer } from "./parsing-B9llLYuO.js";
5
- import { A, E as E2, H, S, c, i, e, p, d, f, g } from "./parsing-B9llLYuO.js";
3
+ import { h as hashToken$1, s as signFp$1, a as signDataFp$1, v as validateFp$1, b as bufferToArrayBuffer } from "./parsing-Cn-1lfce.js";
4
+ import { A, E, H, S, c, i, e, p, d, f, g } from "./parsing-Cn-1lfce.js";
6
5
  import { deepSnakeToCamelObjKeys } from "@tma.js/toolkit";
7
6
  function textToBuffer(text) {
8
7
  return Buffer.from(typeof text === "string" ? text : new Uint8Array(text));
@@ -16,18 +15,18 @@ function hashToken(token) {
16
15
  return Buffer.from(hashToken$1(token, createHmac));
17
16
  }
18
17
  function isValid(value, token, options) {
19
- return pipe(
18
+ return _function.pipe(
20
19
  validateFp(value, token, options),
21
- E.match(() => false, () => true)
20
+ either.match(() => false, () => true)
22
21
  );
23
22
  }
24
23
  function signFp(data, key, authDate, options) {
25
24
  return signFp$1(data, key, authDate, signDataFp, options);
26
25
  }
27
26
  function sign(data, key, authDate, options) {
28
- return pipe(
27
+ return _function.pipe(
29
28
  signFp(data, key, authDate, options),
30
- E.match((e2) => {
29
+ either.match((e2) => {
31
30
  throw e2;
32
31
  }, (v) => v)
33
32
  );
@@ -36,9 +35,9 @@ function signDataFp(data, key, options) {
36
35
  return signDataFp$1(false, data, key, createHmac, options);
37
36
  }
38
37
  function signData(data, key, options) {
39
- return pipe(
38
+ return _function.pipe(
40
39
  signDataFp(data, key, options),
41
- E.match((e2) => {
40
+ either.match((e2) => {
42
41
  throw e2;
43
42
  }, (v) => v)
44
43
  );
@@ -47,16 +46,16 @@ function validateFp(value, token, options) {
47
46
  return validateFp$1(false, value, token, signDataFp, options);
48
47
  }
49
48
  function validate(value, token, options) {
50
- pipe(
49
+ _function.pipe(
51
50
  validateFp(value, token, options),
52
- E.mapLeft((error) => {
51
+ either.mapLeft((error) => {
53
52
  throw error;
54
53
  })
55
54
  );
56
55
  }
57
56
  export {
58
57
  A as AuthDateInvalidError,
59
- E2 as ExpiredError,
58
+ E as ExpiredError,
60
59
  H as HexStringLengthInvalidError,
61
60
  S as SignatureInvalidError,
62
61
  c as SignatureMissingError,
@@ -1 +1 @@
1
- {"version":3,"file":"node.js","sources":["../../src/entries/node.ts"],"sourcesContent":["import * as E from 'fp-ts/Either';\nimport { pipe } from 'fp-ts/lib/function.js';\nimport { createHmac as nodeCreateHmac } from 'node:crypto';\n\nimport { bufferToArrayBuffer } from '../buf-converters.js';\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 ValidateError,\n type ValidateOptions,\n type ValidateValue,\n} from '../validation.js';\n\n/**\n * Converts Text to Node.js Buffer.\n * @param text - text to convert\n */\nfunction textToBuffer(text: Text): Buffer {\n return Buffer.from(typeof text === 'string' ? text : new Uint8Array(text));\n}\n\nconst createHmac: CreateHmacFn<false> = (data, key) => {\n return bufferToArrayBuffer(\n nodeCreateHmac('sha256', textToBuffer(key))\n .update(textToBuffer(data))\n .digest(),\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): Buffer {\n return Buffer.from(_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 isValid(value: ValidateValue, token: Text, options?: ValidateOptions): boolean {\n return pipe(\n validateFp(value, token, options),\n E.match(() => false, () => true),\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): E.Either<SignDataError, string> {\n return _signFp(data, key, authDate, signDataFp, options);\n}\n\n/**\n * @see signFp\n */\nexport function sign(data: SignableData, key: Text, authDate: Date, options?: SignOptions): string {\n return pipe(\n signFp(data, key, authDate, options),\n E.match(e => {\n throw e;\n }, v => v),\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): E.Either<SignDataError, string> {\n return _signDataFp(false, data, key, createHmac, options);\n}\n\n/**\n * @see signDataFp\n */\nexport function signData(data: Text, key: Text, options?: SignDataOptions): string {\n return pipe(\n signDataFp(data, key, options),\n E.match(e => {\n throw e;\n }, v => v),\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?: ValidateOptions,\n): E.Either<ValidateError, void> {\n return _validateFp(false, value, token, signDataFp, options);\n}\n\n/**\n * @see validateFp\n */\nexport function validate(value: ValidateValue, token: Text, options?: ValidateOptions): void {\n pipe(\n validateFp(value, token, options),\n E.mapLeft(error => {\n throw error;\n }),\n );\n}\n\nexport * from './shared.js';\n"],"names":["nodeCreateHmac","_hashToken","_signFp","e","_signDataFp","_validateFp"],"mappings":";;;;;;AAwBA,SAAS,aAAa,MAAoB;AACjC,SAAA,OAAO,KAAK,OAAO,SAAS,WAAW,OAAO,IAAI,WAAW,IAAI,CAAC;AAC3E;AAEA,MAAM,aAAkC,CAAC,MAAM,QAAQ;AAC9C,SAAA;AAAA,IACLA,aAAe,UAAU,aAAa,GAAG,CAAC,EACvC,OAAO,aAAa,IAAI,CAAC,EACzB,OAAO;AAAA,EACZ;AACF;AAMO,SAAS,UAAU,OAAqB;AAC7C,SAAO,OAAO,KAAKC,YAAW,OAAO,UAAU,CAAC;AAClD;AAQgB,SAAA,QAAQ,OAAsB,OAAa,SAAoC;AACtF,SAAA;AAAA,IACL,WAAW,OAAO,OAAO,OAAO;AAAA,IAChC,EAAE,MAAM,MAAM,OAAO,MAAM,IAAI;AAAA,EACjC;AACF;AAUO,SAAS,OACd,MACA,KACA,UACA,SACiC;AACjC,SAAOC,SAAQ,MAAM,KAAK,UAAU,YAAY,OAAO;AACzD;AAKO,SAAS,KAAK,MAAoB,KAAW,UAAgB,SAA+B;AAC1F,SAAA;AAAA,IACL,OAAO,MAAM,KAAK,UAAU,OAAO;AAAA,IACnC,EAAE,MAAM,CAAKC,OAAA;AACL,YAAAA;AAAA,IAAA,GACL,OAAK,CAAC;AAAA,EACX;AACF;AASgB,SAAA,WACd,MACA,KACA,SACiC;AACjC,SAAOC,aAAY,OAAO,MAAM,KAAK,YAAY,OAAO;AAC1D;AAKgB,SAAA,SAAS,MAAY,KAAW,SAAmC;AAC1E,SAAA;AAAA,IACL,WAAW,MAAM,KAAK,OAAO;AAAA,IAC7B,EAAE,MAAM,CAAKD,OAAA;AACL,YAAAA;AAAA,IAAA,GACL,OAAK,CAAC;AAAA,EACX;AACF;AAQgB,SAAA,WACd,OACA,OACA,SAC+B;AAC/B,SAAOE,aAAY,OAAO,OAAO,OAAO,YAAY,OAAO;AAC7D;AAKgB,SAAA,SAAS,OAAsB,OAAa,SAAiC;AAC3F;AAAA,IACE,WAAW,OAAO,OAAO,OAAO;AAAA,IAChC,EAAE,QAAQ,CAAS,UAAA;AACX,YAAA;AAAA,IACP,CAAA;AAAA,EACH;AACF;"}
1
+ {"version":3,"file":"node.js","sources":["../../src/entries/node.ts"],"sourcesContent":["import { either as E, function as fn } from 'fp-ts';\nimport { createHmac as nodeCreateHmac } from 'node:crypto';\n\nimport { bufferToArrayBuffer } from '../buf-converters.js';\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 ValidateError,\n type ValidateOptions,\n type ValidateValue,\n} from '../validation.js';\n\n/**\n * Converts Text to NodE.js Buffer.\n * @param text - text to convert\n */\nfunction textToBuffer(text: Text): Buffer {\n return Buffer.from(typeof text === 'string' ? text : new Uint8Array(text));\n}\n\nconst createHmac: CreateHmacFn<false> = (data, key) => {\n return bufferToArrayBuffer(\n nodeCreateHmac('sha256', textToBuffer(key))\n .update(textToBuffer(data))\n .digest(),\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): Buffer {\n return Buffer.from(_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 isValid(value: ValidateValue, token: Text, options?: ValidateOptions): boolean {\n return fn.pipe(\n validateFp(value, token, options),\n E.match(() => false, () => true),\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): E.Either<SignDataError, string> {\n return _signFp(data, key, authDate, signDataFp, options);\n}\n\n/**\n * @see signFp\n */\nexport function sign(data: SignableData, key: Text, authDate: Date, options?: SignOptions): string {\n return fn.pipe(\n signFp(data, key, authDate, options),\n E.match(e => {\n throw e;\n }, v => v),\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): E.Either<SignDataError, string> {\n return _signDataFp(false, data, key, createHmac, options);\n}\n\n/**\n * @see signDataFp\n */\nexport function signData(data: Text, key: Text, options?: SignDataOptions): string {\n return fn.pipe(\n signDataFp(data, key, options),\n E.match(e => {\n throw e;\n }, v => v),\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?: ValidateOptions,\n): E.Either<ValidateError, void> {\n return _validateFp(false, value, token, signDataFp, options);\n}\n\n/**\n * @see validateFp\n */\nexport function validate(value: ValidateValue, token: Text, options?: ValidateOptions): void {\n fn.pipe(\n validateFp(value, token, options),\n E.mapLeft(error => {\n throw error;\n }),\n );\n}\n\nexport * from './shared.js';\n"],"names":["nodeCreateHmac","_hashToken","fn","E","_signFp","e","_signDataFp","_validateFp"],"mappings":";;;;;AAuBA,SAAS,aAAa,MAAoB;AACjC,SAAA,OAAO,KAAK,OAAO,SAAS,WAAW,OAAO,IAAI,WAAW,IAAI,CAAC;AAC3E;AAEA,MAAM,aAAkC,CAAC,MAAM,QAAQ;AAC9C,SAAA;AAAA,IACLA,aAAe,UAAU,aAAa,GAAG,CAAC,EACvC,OAAO,aAAa,IAAI,CAAC,EACzB,OAAO;AAAA,EACZ;AACF;AAMO,SAAS,UAAU,OAAqB;AAC7C,SAAO,OAAO,KAAKC,YAAW,OAAO,UAAU,CAAC;AAClD;AAQgB,SAAA,QAAQ,OAAsB,OAAa,SAAoC;AAC7F,SAAOC,UAAG;AAAA,IACR,WAAW,OAAO,OAAO,OAAO;AAAA,IAChCC,OAAE,MAAM,MAAM,OAAO,MAAM,IAAI;AAAA,EACjC;AACF;AAUO,SAAS,OACd,MACA,KACA,UACA,SACiC;AACjC,SAAOC,SAAQ,MAAM,KAAK,UAAU,YAAY,OAAO;AACzD;AAKO,SAAS,KAAK,MAAoB,KAAW,UAAgB,SAA+B;AACjG,SAAOF,UAAG;AAAA,IACR,OAAO,MAAM,KAAK,UAAU,OAAO;AAAA,IACnCC,OAAE,MAAM,CAAKE,OAAA;AACL,YAAAA;AAAA,IAAA,GACL,OAAK,CAAC;AAAA,EACX;AACF;AASgB,SAAA,WACd,MACA,KACA,SACiC;AACjC,SAAOC,aAAY,OAAO,MAAM,KAAK,YAAY,OAAO;AAC1D;AAKgB,SAAA,SAAS,MAAY,KAAW,SAAmC;AACjF,SAAOJ,UAAG;AAAA,IACR,WAAW,MAAM,KAAK,OAAO;AAAA,IAC7BC,OAAE,MAAM,CAAKE,OAAA;AACL,YAAAA;AAAA,IAAA,GACL,OAAK,CAAC;AAAA,EACX;AACF;AAQgB,SAAA,WACd,OACA,OACA,SAC+B;AAC/B,SAAOE,aAAY,OAAO,OAAO,OAAO,YAAY,OAAO;AAC7D;AAKgB,SAAA,SAAS,OAAsB,OAAa,SAAiC;AACxFL,YAAA;AAAA,IACD,WAAW,OAAO,OAAO,OAAO;AAAA,IAChCC,OAAE,QAAQ,CAAS,UAAA;AACX,YAAA;AAAA,IACP,CAAA;AAAA,EACH;AACF;"}
@@ -1,64 +1,41 @@
1
1
  "use strict";
2
- const E = require("fp-ts/Either");
3
- const TE = require("fp-ts/TaskEither");
4
- const function_js = require("fp-ts/lib/function.js");
2
+ const fpTs = require("fp-ts");
5
3
  const transformers = require("@tma.js/transformers");
6
4
  const betterPromises = require("better-promises");
7
- const _function = require("fp-ts/function");
8
5
  const errorKid = require("error-kid");
9
- function _interopNamespaceDefault(e) {
10
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
11
- if (e) {
12
- for (const k in e) {
13
- if (k !== "default") {
14
- const d = Object.getOwnPropertyDescriptor(e, k);
15
- Object.defineProperty(n, k, d.get ? d : {
16
- enumerable: true,
17
- get: () => e[k]
18
- });
19
- }
20
- }
21
- }
22
- n.default = e;
23
- return Object.freeze(n);
24
- }
25
- const E__namespace = /* @__PURE__ */ _interopNamespaceDefault(E);
26
- const TE__namespace = /* @__PURE__ */ _interopNamespaceDefault(TE);
27
- class AuthDateInvalidError extends errorKid.errorClassWithData(
28
- "AuthDateInvalidError",
29
- (value) => ({ value }),
30
- (value) => [`"auth_date" is invalid: ${value || "value is missing"}`]
31
- ) {
6
+ class AuthDateInvalidError extends errorKid.errorClassWithData({
7
+ name: "AuthDateInvalidError",
8
+ data: (value) => ({ value }),
9
+ super: (value) => [`"auth_date" is invalid: ${value || "value is missing"}`]
10
+ }) {
32
11
  }
33
- class SignatureInvalidError extends errorKid.errorClass("SignatureInvalidError") {
12
+ class SignatureInvalidError extends errorKid.errorClass({ name: "SignatureInvalidError" }) {
34
13
  }
35
- class HexStringLengthInvalidError extends errorKid.errorClass(
36
- "HexStringLengthInvalidError"
37
- ) {
14
+ class HexStringLengthInvalidError extends errorKid.errorClass({ name: "HexStringLengthInvalidError" }) {
38
15
  }
39
- class SignatureMissingError extends errorKid.errorClass(
40
- "SignatureMissingError",
41
- (thirdParty) => [`"${thirdParty ? "signature" : "hash"}" parameter is missing`]
42
- ) {
16
+ class SignatureMissingError extends errorKid.errorClass({
17
+ name: "SignatureMissingError",
18
+ super: (thirdParty) => [`"${thirdParty ? "signature" : "hash"}" parameter is missing`]
19
+ }) {
43
20
  }
44
- class ExpiredError extends errorKid.errorClassWithData(
45
- "ExpiredError",
46
- (issuedAt, expiresAt) => ({ issuedAt, expiresAt }),
47
- (issuedAt, expiresAt, now) => [
21
+ class ExpiredError extends errorKid.errorClassWithData({
22
+ name: "ExpiredError",
23
+ data: (issuedAt, expiresAt) => ({ issuedAt, expiresAt }),
24
+ super: (issuedAt, expiresAt, now) => [
48
25
  `Init data expired. Issued at ${issuedAt.toISOString()}, expires at ${expiresAt.toISOString()}, now is ${now.toISOString()}`
49
26
  ]
50
- ) {
27
+ }) {
51
28
  }
52
29
  function hexToArrayBuffer(hexString) {
53
30
  if (hexString.length % 2 !== 0) {
54
- return E__namespace.left(new HexStringLengthInvalidError());
31
+ return fpTs.either.left(new HexStringLengthInvalidError());
55
32
  }
56
33
  const buffer = new ArrayBuffer(hexString.length / 2);
57
34
  const uint8Array = new Uint8Array(buffer);
58
35
  for (let i = 0; i < hexString.length; i += 2) {
59
36
  uint8Array[i / 2] = parseInt(hexString.substring(i, i + 2), 16);
60
37
  }
61
- return E__namespace.right(buffer);
38
+ return fpTs.either.right(buffer);
62
39
  }
63
40
  function arrayBufferToHex(arrBuf) {
64
41
  return new Uint8Array(arrBuf).reduce((acc, byte) => {
@@ -74,26 +51,26 @@ function hashToken(token, createHmac) {
74
51
  return createHmac(token, "WebAppData");
75
52
  }
76
53
  function signDataFp(async, data, key, createHmac, options = {}) {
77
- const keyHmac = options.tokenHashed ? typeof key === "string" ? hexToArrayBuffer(key) : E__namespace.right(key) : function_js.pipe(
78
- E__namespace.right(hashToken(key, createHmac)),
79
- E__namespace.match(() => null, (v) => {
80
- return v instanceof Promise ? TE__namespace.tryCatch(() => v, (err) => err) : E__namespace.right(v);
54
+ const keyHmac = options.tokenHashed ? typeof key === "string" ? hexToArrayBuffer(key) : fpTs.either.right(key) : fpTs.function.pipe(
55
+ fpTs.either.right(hashToken(key, createHmac)),
56
+ fpTs.either.match(() => null, (v) => {
57
+ return v instanceof Promise ? fpTs.taskEither.tryCatch(() => v, (err) => err) : fpTs.either.right(v);
81
58
  })
82
59
  );
83
60
  if (async || typeof keyHmac === "function") {
84
- return function_js.pipe(
85
- typeof keyHmac === "function" ? keyHmac : TE__namespace.fromEither(keyHmac),
86
- TE__namespace.chain((v) => TE__namespace.tryCatch(
61
+ return fpTs.function.pipe(
62
+ typeof keyHmac === "function" ? keyHmac : fpTs.taskEither.fromEither(keyHmac),
63
+ fpTs.taskEither.chainW((v) => fpTs.taskEither.tryCatch(
87
64
  () => Promise.resolve(createHmac(data, v)).then(arrayBufferToHex),
88
65
  (err) => err
89
66
  ))
90
67
  );
91
68
  }
92
- return function_js.pipe(
69
+ return fpTs.function.pipe(
93
70
  keyHmac,
94
71
  // In this branch createHmac can't be asynchronous. If it is, keyHmac would be Promise and the
95
72
  // result would be returned in the previous "if" statement.
96
- E__namespace.chain((v) => E__namespace.right(
73
+ fpTs.either.chain((v) => fpTs.either.right(
97
74
  arrayBufferToHex(createHmac(data, v))
98
75
  ))
99
76
  );
@@ -110,7 +87,7 @@ function signFp(data, key, authDate, signData, options) {
110
87
  return query.toString();
111
88
  };
112
89
  const eitherHash = signData(pairs.join("\n"), key, options);
113
- return typeof eitherHash === "function" ? function_js.pipe(eitherHash, TE__namespace.chain((hash) => TE__namespace.right(queryWithHash(hash)))) : function_js.pipe(eitherHash, E__namespace.chain((hash) => E__namespace.right(queryWithHash(hash))));
90
+ return typeof eitherHash === "function" ? fpTs.function.pipe(eitherHash, fpTs.taskEither.chain((hash) => fpTs.taskEither.right(queryWithHash(hash)))) : fpTs.function.pipe(eitherHash, fpTs.either.chain((hash) => fpTs.either.right(queryWithHash(hash))));
114
91
  }
115
92
  function validate3rdFp(value, botId, options = {}) {
116
93
  let authDate;
@@ -135,21 +112,21 @@ function validate3rdFp(value, botId, options = {}) {
135
112
  pairs.push(`${key}=${value2}`);
136
113
  });
137
114
  if (!signature) {
138
- return TE__namespace.left(new SignatureMissingError(true));
115
+ return fpTs.taskEither.left(new SignatureMissingError(true));
139
116
  }
140
117
  if (!authDate) {
141
- return TE__namespace.left(new AuthDateInvalidError(authDateString));
118
+ return fpTs.taskEither.left(new AuthDateInvalidError(authDateString));
142
119
  }
143
120
  const { expiresIn = 86400 } = options;
144
121
  if (expiresIn > 0) {
145
122
  const expiresAtTs = authDate.getTime() + expiresIn * 1e3;
146
123
  const nowTs = Date.now();
147
124
  if (expiresAtTs < nowTs) {
148
- return TE__namespace.left(new ExpiredError(authDate, new Date(expiresAtTs), new Date(nowTs)));
125
+ return fpTs.taskEither.left(new ExpiredError(authDate, new Date(expiresAtTs), new Date(nowTs)));
149
126
  }
150
127
  }
151
- return _function.pipe(
152
- TE__namespace.tryCatch(
128
+ return fpTs.function.pipe(
129
+ fpTs.taskEither.tryCatch(
153
130
  () => {
154
131
  return betterPromises.BetterPromise.fn(async () => {
155
132
  return crypto.subtle.verify(
@@ -173,31 +150,31 @@ ${pairs.sort().join("\n")}`)
173
150
  },
174
151
  (e) => e
175
152
  ),
176
- TE__namespace.chainW((isVerified) => {
177
- return isVerified ? TE__namespace.right(void 0) : TE__namespace.left(new SignatureInvalidError());
153
+ fpTs.taskEither.chainW((isVerified) => {
154
+ return isVerified ? fpTs.taskEither.right(void 0) : fpTs.taskEither.left(new SignatureInvalidError());
178
155
  })
179
156
  );
180
157
  }
181
158
  function validate3rd(value, botId, options) {
182
159
  return betterPromises.BetterPromise.fn(async () => {
183
- await _function.pipe(
160
+ await fpTs.function.pipe(
184
161
  validate3rdFp(value, botId, options),
185
- TE__namespace.mapLeft((error) => {
162
+ fpTs.taskEither.mapLeft((error) => {
186
163
  throw error;
187
164
  })
188
165
  )();
189
166
  });
190
167
  }
191
168
  function isValid3rdFp(value, botId, options) {
192
- return _function.pipe(validate3rdFp(value, botId, options), TE__namespace.match(
193
- () => E__namespace.right(false),
194
- () => E__namespace.right(true)
169
+ return fpTs.function.pipe(validate3rdFp(value, botId, options), fpTs.taskEither.match(
170
+ () => fpTs.either.right(false),
171
+ () => fpTs.either.right(true)
195
172
  ));
196
173
  }
197
174
  function isValid3rd(value, botId, options) {
198
- return betterPromises.BetterPromise.fn(() => _function.pipe(
175
+ return betterPromises.BetterPromise.fn(() => fpTs.function.pipe(
199
176
  isValid3rdFp(value, botId, options),
200
- TE__namespace.match(() => false, (v) => v)
177
+ fpTs.taskEither.match(() => false, (v) => v)
201
178
  )());
202
179
  }
203
180
  function validateFp(async, value, token, signData, options = {}) {
@@ -220,26 +197,26 @@ function validateFp(async, value, token, signData, options = {}) {
220
197
  pairs.push(`${key}=${value2}`);
221
198
  });
222
199
  if (!hash) {
223
- return (async ? TE__namespace.left : E__namespace.left)(new SignatureMissingError(false));
200
+ return (async ? fpTs.taskEither.left : fpTs.either.left)(new SignatureMissingError(false));
224
201
  }
225
202
  if (!authDate) {
226
- return (async ? TE__namespace.left : E__namespace.left)(new AuthDateInvalidError(authDateString));
203
+ return (async ? fpTs.taskEither.left : fpTs.either.left)(new AuthDateInvalidError(authDateString));
227
204
  }
228
205
  const { expiresIn = 86400 } = options;
229
206
  if (expiresIn > 0) {
230
207
  const expiresAtTs = authDate.getTime() + expiresIn * 1e3;
231
208
  const nowTs = Date.now();
232
209
  if (expiresAtTs < nowTs) {
233
- return (async ? TE__namespace.left : E__namespace.left)(
210
+ return (async ? fpTs.taskEither.left : fpTs.either.left)(
234
211
  new ExpiredError(authDate, new Date(expiresAtTs), new Date(nowTs))
235
212
  );
236
213
  }
237
214
  }
238
215
  pairs.sort();
239
216
  const eitherSignature = signData(pairs.join("\n"), token, options);
240
- const onLeft = (error) => E__namespace.left(error);
241
- const onRight = (signature) => signature === hash ? E__namespace.right(void 0) : E__namespace.left(new SignatureInvalidError());
242
- return typeof eitherSignature === "function" ? _function.pipe(eitherSignature, TE__namespace.matchW(onLeft, onRight)) : _function.pipe(eitherSignature, E__namespace.matchW(onLeft, onRight));
217
+ const onLeft = (error) => fpTs.either.left(error);
218
+ const onRight = (signature) => signature === hash ? fpTs.either.right(void 0) : fpTs.either.left(new SignatureInvalidError());
219
+ return typeof eitherSignature === "function" ? fpTs.function.pipe(eitherSignature, fpTs.taskEither.matchW(onLeft, onRight)) : fpTs.function.pipe(eitherSignature, fpTs.either.matchW(onLeft, onRight));
243
220
  }
244
221
  const parse = transformers.parseInitDataQuery;
245
222
  const parseFp = transformers.parseInitDataQueryFp;
@@ -259,4 +236,4 @@ exports.signFp = signFp;
259
236
  exports.validate3rd = validate3rd;
260
237
  exports.validate3rdFp = validate3rdFp;
261
238
  exports.validateFp = validateFp;
262
- //# sourceMappingURL=parsing-pEQ1lsuE.cjs.map
239
+ //# sourceMappingURL=parsing-BMJa8cb6.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parsing-BMJa8cb6.cjs","sources":["../../src/errors.ts","../../src/buf-converters.ts","../../src/hashToken.ts","../../src/signDataFp.ts","../../src/signFp.ts","../../src/validation.ts","../../src/parsing.ts"],"sourcesContent":["import { errorClass, errorClassWithData } from 'error-kid';\n\nexport class AuthDateInvalidError extends errorClassWithData<\n { value: string | undefined },\n [value?: string]\n>({\n name: 'AuthDateInvalidError',\n data: value => ({ value }),\n super: value => [`\"auth_date\" is invalid: ${value || 'value is missing'}`],\n}) {\n}\n\nexport class SignatureInvalidError extends errorClass({ name: 'SignatureInvalidError' }) {\n}\n\nexport class HexStringLengthInvalidError extends errorClass({ name: 'HexStringLengthInvalidError' }) {\n}\n\nexport class SignatureMissingError extends errorClass<[thirdParty: boolean]>({\n name: 'SignatureMissingError',\n super: thirdParty => [`\"${thirdParty ? 'signature' : 'hash'}\" parameter is missing`],\n}) {\n}\n\nexport class ExpiredError extends errorClassWithData<\n { issuedAt: Date; expiresAt: Date },\n [issuedAt: Date, expiresAt: Date, now: Date]\n>({\n name: 'ExpiredError',\n data: (issuedAt, expiresAt) => ({ issuedAt, expiresAt }),\n super: (issuedAt, expiresAt, now) => [\n `Init data expired. Issued at ${issuedAt.toISOString()}, expires at ${expiresAt.toISOString()}, now is ${now.toISOString()}`,\n ],\n}) {\n}\n","import { either as E } from 'fp-ts';\n\nimport { HexStringLengthInvalidError } from './errors.js';\n\n/**\n * Converts a hex string to ArrayBuffer.\n * @param hexString - value to convert.\n */\nexport function hexToArrayBuffer(hexString: string): E.Either<\n InstanceType<typeof HexStringLengthInvalidError>,\n ArrayBuffer\n> {\n if (hexString.length % 2 !== 0) {\n return E.left(new HexStringLengthInvalidError());\n }\n const buffer = new ArrayBuffer(hexString.length / 2);\n const uint8Array = new Uint8Array(buffer);\n for (let i = 0; i < hexString.length; i += 2) {\n uint8Array[i / 2] = parseInt(hexString.substring(i, i + 2), 16);\n }\n return E.right(buffer);\n}\n\n/**\n * Converts array buffer to hex.\n * @param arrBuf - buffer to convert\n */\nexport function arrayBufferToHex(arrBuf: ArrayBuffer): string {\n return new Uint8Array(arrBuf).reduce((acc, byte) => {\n // Convert byte to hex and pad with zero if needed (e.g., \"0a\" instead of \"a\")\n return acc + byte.toString(16).padStart(2, '0');\n }, '');\n}\n\nexport function bufferToArrayBuffer(buf: Buffer) {\n const ab = new ArrayBuffer(buf.length);\n buf.copy(new Uint8Array(ab));\n return ab;\n}\n","import type { CreateHmacFn, Text } from './types.js';\n\nexport function hashToken<H extends CreateHmacFn<any>>(token: Text, createHmac: H): ReturnType<H> {\n return createHmac(token, 'WebAppData') as ReturnType<H>;\n}\n","import { either as E, taskEither as TE, function as fn } from 'fp-ts';\n\nimport { arrayBufferToHex, hexToArrayBuffer } from './buf-converters.js';\nimport { hashToken } from './hashToken.js';\nimport type { CreateHmacFn, Text } from './types.js';\n\nexport interface SignDataOptions {\n /**\n * True, if token is already hashed and doesn't require hashing using HMAC-SHA-256.\n */\n tokenHashed?: boolean;\n}\n\nexport type SignDataError = ReturnType<typeof hexToArrayBuffer> extends E.Either<infer U, any>\n ? U\n : never;\n\nexport function signDataFp(\n async: false,\n data: Text,\n key: Text,\n createHmac: CreateHmacFn<false>,\n options?: SignDataOptions,\n): E.Either<SignDataError, string>;\n\nexport function signDataFp(\n async: true,\n data: Text,\n key: Text,\n createHmac: CreateHmacFn<true>,\n options?: SignDataOptions,\n): TE.TaskEither<SignDataError, string>;\n\nexport function signDataFp(\n async: boolean,\n data: Text,\n key: Text,\n createHmac: CreateHmacFn<boolean>,\n options: SignDataOptions = {},\n):\n | E.Either<SignDataError, string>\n | TE.TaskEither<SignDataError, string> {\n const keyHmac = options.tokenHashed\n ? typeof key === 'string'\n // If a hashed token was passed, we assume that it is a HEX string. Not to mess with\n // the createHmac function, we should convert this HEX string to ArrayBuffer. Otherwise,\n // incorrect behavior will be met.\n ? hexToArrayBuffer(key)\n : E.right(key)\n // Otherwise we are hashing the token, but we want it to be a monad.\n : fn.pipe(\n E.right(hashToken(key, createHmac)),\n E.match(() => null as never, v => {\n return v instanceof Promise\n ? TE.tryCatch(() => v, err => err as never)\n : E.right(v);\n }),\n );\n\n if (async || typeof keyHmac === 'function') {\n return fn.pipe(\n typeof keyHmac === 'function' ? keyHmac : TE.fromEither(keyHmac),\n TE.chainW(v => TE.tryCatch(\n () => Promise.resolve(createHmac(data, v)).then(arrayBufferToHex),\n err => err as never,\n )),\n );\n }\n return fn.pipe(\n keyHmac,\n // In this branch createHmac can't be asynchronous. If it is, keyHmac would be Promise and the\n // result would be returned in the previous \"if\" statement.\n E.chain(v => E.right(\n arrayBufferToHex((createHmac as CreateHmacFn<false>)(data, v)),\n )),\n );\n}\n","import { type InitDataLike, serializeInitDataQuery } from '@tma.js/transformers';\nimport { either as E, taskEither as TE, function as fn } from 'fp-ts';\n\nimport type { Text } from './types.js';\n\nexport type SignableData =\n & Omit<InitDataLike, 'auth_date' | 'hash' | 'signature'>\n & { signature?: string };\n\nexport interface SignOptions {\n /**\n * True, if token is already hashed and doesn't require hashing using HMAC-SHA-256.\n */\n tokenHashed?: boolean;\n}\n\ninterface SignDataFpArg<Async extends boolean, Left> {\n (data: Text, key: Text, options?: SignOptions): Async extends true\n ? TE.TaskEither<Left, string>\n : E.Either<Left, string>;\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 signData - function signing data.\n * @param options - additional options.\n * @returns Signed init data presented as query parameters.\n */\nexport function signFp<Left>(\n data: SignableData,\n key: Text,\n authDate: Date,\n signData: SignDataFpArg<false, Left>,\n options?: SignOptions,\n): E.Either<Left, string>;\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 signData - function signing data.\n * @param options - additional options.\n * @returns Signed init data presented as query parameters.\n */\nexport function signFp<Left>(\n data: SignableData,\n key: Text,\n authDate: Date,\n signData: SignDataFpArg<true, Left>,\n options?: SignOptions,\n): TE.TaskEither<Left, string>;\n\nexport function signFp<Left>(\n data: SignableData,\n key: Text,\n authDate: Date,\n signData: SignDataFpArg<boolean, Left>,\n options?: SignOptions,\n): E.Either<Left, string> | TE.TaskEither<Left, string> {\n const query = new URLSearchParams(serializeInitDataQuery({\n ...data,\n auth_date: authDate,\n signature: data.signature || '',\n }));\n\n // Convert search params to pairs and sort the final array.\n const pairs = [...query.entries()]\n .map(([name, value]) => `${name}=${value}`)\n .sort();\n\n // Compute sign, append it to the params and return.\n const queryWithHash = (signature: string): string => {\n query.append('hash', signature);\n return query.toString();\n };\n\n const eitherHash = signData(pairs.join('\\n'), key, options);\n return typeof eitherHash === 'function'\n ? fn.pipe(eitherHash, TE.chain(hash => TE.right(queryWithHash(hash))))\n : fn.pipe(eitherHash, E.chain(hash => E.right(queryWithHash(hash))));\n}\n","import {\n BetterPromise,\n type BetterPromiseOptions,\n type BetterPromiseRejectReason,\n} from 'better-promises';\nimport { either as E, taskEither as TE, function as fn } from 'fp-ts';\n\nimport {\n AuthDateInvalidError,\n ExpiredError,\n SignatureInvalidError,\n SignatureMissingError,\n} from './errors.js';\nimport { Text } from './types.js';\n\ntype OmittedPromiseOptions = Omit<BetterPromiseOptions, 'abortOnResolve' | 'abortOnReject'>;\n\nexport type ValidateValue = string | URLSearchParams;\nexport type Validate3rdValue = string | URLSearchParams;\n\nexport type ValidateError =\n | SignatureMissingError\n | SignatureInvalidError\n | AuthDateInvalidError\n | ExpiredError;\nexport type ValidateAsyncError = ValidateError | BetterPromiseRejectReason;\nexport type Validate3rdError =\n | SignatureMissingError\n | SignatureInvalidError\n | AuthDateInvalidError\n | ExpiredError\n | BetterPromiseRejectReason;\n\ninterface ValidateSignDataFpArg<Async extends boolean, Left> {\n (data: Text, key: Text, options?: ValidateOptions): Async extends true\n ? TE.TaskEither<Left, string>\n : E.Either<Left, string>;\n}\n\ninterface SharedValidateOptions {\n /**\n * Time in seconds which states, how long from creation time init data is considered valid.\n *\n * In other words, in case when authDate + expiresIn is before current time, init data is\n * recognized as expired.\n *\n * In case this value is equal to 0, the function does not check init data expiration.\n * @default 86400 (1 day)\n */\n expiresIn?: number;\n}\n\nexport interface ValidateOptions extends SharedValidateOptions {\n /**\n * True, if token is already hashed.\n * @default false\n */\n tokenHashed?: boolean;\n}\n\nexport interface ValidateAsyncOptions extends ValidateOptions, OmittedPromiseOptions {\n}\n\nexport interface Validate3rdOptions extends SharedValidateOptions, OmittedPromiseOptions {\n /**\n * When true, uses the test environment public key to validate init data.\n * @default false\n */\n test?: boolean;\n}\n\n/**\n * Validates passed init data using a publicly known Ee25519 key.\n * @param value - value to check.\n * @param botId - bot identifier\n * @param options - additional validation options.\n */\nexport function validate3rdFp(\n value: Validate3rdValue,\n botId: number,\n options: Validate3rdOptions = {},\n): TE.TaskEither<Validate3rdError, void> {\n // Init data required params.\n let authDate: Date | undefined;\n let authDateString: string | undefined;\n let signature: string | undefined;\n\n // All search params pairs presented as `k=v`.\n const pairs: string[] = [];\n\n // Iterate over all key-value pairs of parsed parameters and find required\n // parameters.\n (typeof value === 'string' ? new URLSearchParams(value) : value).forEach((value, key) => {\n if (key === 'hash') {\n return;\n }\n if (key === 'signature') {\n signature = value;\n return;\n }\n if (key === 'auth_date') {\n authDateString = value;\n const authDateNum = parseInt(value, 10);\n if (!Number.isNaN(authDateNum)) {\n authDate = new Date(authDateNum * 1000);\n }\n }\n\n pairs.push(`${key}=${value}`);\n });\n\n // Signature and auth date always required.\n if (!signature) {\n return TE.left(new SignatureMissingError(true));\n }\n\n if (!authDate) {\n return TE.left(new AuthDateInvalidError(authDateString));\n }\n\n // In case, expiration time passed, we do additional parameters check.\n const { expiresIn = 86400 } = options;\n if (expiresIn > 0) {\n // Check if init data expired.\n const expiresAtTs = authDate.getTime() + (expiresIn * 1000);\n const nowTs = Date.now();\n if (expiresAtTs < nowTs) {\n return TE.left(new ExpiredError(authDate, new Date(expiresAtTs), new Date(nowTs)));\n }\n }\n\n return fn.pipe(\n TE.tryCatch(\n () => {\n return BetterPromise.fn(async () => {\n return crypto.subtle.verify(\n 'Ed25519',\n await crypto.subtle.importKey(\n 'raw',\n Buffer.from(\n options.test\n ? '40055058a4ee38156a06562e52eece92a771bcd8346a8c4615cb7376eddf72ec'\n : 'e7bf03a2fa4602af4580703d88dda5bb59f32ed8b02a56c187fe7d34caed242d',\n 'hex',\n ),\n 'Ed25519',\n false,\n ['verify'],\n ),\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n Buffer.from(signature as string, 'base64'),\n Buffer.from(`${botId}:WebAppData\\n${pairs.sort().join('\\n')}`),\n );\n }, options);\n },\n (e: unknown) => e,\n ),\n TE.chainW(isVerified => {\n return isVerified\n ? TE.right(undefined)\n : TE.left(new SignatureInvalidError());\n }),\n );\n}\n\n/**\n * @see validate3rdFp\n */\nexport function validate3rd(\n value: Validate3rdValue,\n botId: number,\n options?: Validate3rdOptions,\n): BetterPromise<void> {\n return BetterPromise.fn(async () => {\n await fn.pipe(\n validate3rdFp(value, botId, options),\n TE.mapLeft(error => {\n throw error;\n }),\n )();\n });\n}\n\n/**\n * @param value - value to check.\n * @param botId - bot identifier\n * @param options - additional validation options.\n * @returns True is specified init data is signed by Telegram.\n */\nexport function isValid3rdFp(\n value: Validate3rdValue,\n botId: number,\n options?: Validate3rdOptions,\n): TE.TaskEither<void, boolean> {\n return fn.pipe(validate3rdFp(value, botId, options), TE.match(\n () => E.right(false),\n () => E.right(true),\n ));\n}\n\n/**\n * @see isValid3rdFp\n */\nexport function isValid3rd(\n value: Validate3rdValue,\n botId: number,\n options?: Validate3rdOptions,\n): BetterPromise<boolean> {\n return BetterPromise.fn(() => fn.pipe(\n isValid3rdFp(value, botId, options),\n TE.match(() => false, v => v),\n )());\n}\n\nexport function validateFp<Left>(\n async: false,\n value: ValidateValue,\n token: Text,\n signData: ValidateSignDataFpArg<false, Left>,\n options?: ValidateOptions,\n): E.Either<Left | ValidateError, void>;\n\nexport function validateFp<Left>(\n async: true,\n value: ValidateValue,\n token: Text,\n signData: ValidateSignDataFpArg<true, Left>,\n options?: ValidateAsyncOptions,\n): TE.TaskEither<Left | ValidateAsyncError, void>;\n\nexport function validateFp<Left>(\n async: boolean,\n value: ValidateValue,\n token: Text,\n signData: ValidateSignDataFpArg<boolean, Left>,\n options: ValidateOptions | ValidateAsyncOptions = {},\n):\n | E.Either<Left | ValidateError, void>\n | TE.TaskEither<Left | ValidateAsyncError, void> {\n // Init data required params.\n let authDate: Date | undefined;\n let authDateString: string | undefined;\n let hash: string | undefined;\n\n // All search params pairs presented as `k=v`.\n const pairs: string[] = [];\n\n // Iterate over all key-value pairs of parsed parameters and find required\n // parameters.\n (typeof value === 'string' ? new URLSearchParams(value) : value).forEach((value, key) => {\n if (key === 'hash') {\n hash = value;\n return;\n }\n\n if (key === 'auth_date') {\n authDateString = value;\n const authDateNum = parseInt(value, 10);\n if (!Number.isNaN(authDateNum)) {\n authDate = new Date(authDateNum * 1000);\n }\n }\n\n pairs.push(`${key}=${value}`);\n });\n\n // Hash and auth date always required.\n if (!hash) {\n return (async ? TE.left : E.left)(new SignatureMissingError(false));\n }\n\n if (!authDate) {\n return (async ? TE.left : E.left)(new AuthDateInvalidError(authDateString));\n }\n\n // In case, expiration time passed, we do additional parameters check.\n const { expiresIn = 86400 } = options;\n if (expiresIn > 0) {\n // Check if init data expired.\n const expiresAtTs = authDate.getTime() + (expiresIn * 1000);\n const nowTs = Date.now();\n if (expiresAtTs < nowTs) {\n return (async ? TE.left : E.left)(\n new ExpiredError(authDate, new Date(expiresAtTs), new Date(nowTs)),\n );\n }\n }\n\n // According to docs, we sort all the pairs in alphabetical order.\n pairs.sort();\n\n const eitherSignature = signData(pairs.join('\\n'), token, options);\n const onLeft = (error: Left) => E.left(error);\n const onRight = (signature: string) => (\n signature === hash ? E.right(undefined) : E.left(new SignatureInvalidError())\n );\n\n return typeof eitherSignature === 'function'\n ? fn.pipe(eitherSignature, TE.matchW(onLeft, onRight))\n : fn.pipe(eitherSignature, E.matchW(onLeft, onRight));\n}\n","import {\n parseInitDataQuery,\n parseInitDataQueryFp,\n type ParseInitDataQueryError,\n} from '@tma.js/transformers';\n\n/**\n * Parses an incoming value as init data.\n */\nexport const parse = parseInitDataQuery;\n\n/**\n * Parses an incoming value as init data.\n */\nexport const parseFp = parseInitDataQueryFp;\n\nexport { ParseInitDataQueryError as ParseError };\n"],"names":["errorClassWithData","errorClass","E","fn","TE","serializeInitDataQuery","value","BetterPromise","parseInitDataQuery","parseInitDataQueryFp"],"mappings":"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"}
@@ -1,45 +1,40 @@
1
- import * as E from "fp-ts/Either";
2
- import * as TE from "fp-ts/TaskEither";
3
- import { pipe } from "fp-ts/lib/function.js";
1
+ import { either, function as _function, taskEither } from "fp-ts";
4
2
  import { serializeInitDataQuery, parseInitDataQuery, parseInitDataQueryFp } from "@tma.js/transformers";
5
3
  import { BetterPromise } from "better-promises";
6
- import { pipe as pipe$1 } from "fp-ts/function";
7
4
  import { errorClassWithData, errorClass } from "error-kid";
8
- class AuthDateInvalidError extends errorClassWithData(
9
- "AuthDateInvalidError",
10
- (value) => ({ value }),
11
- (value) => [`"auth_date" is invalid: ${value || "value is missing"}`]
12
- ) {
13
- }
14
- class SignatureInvalidError extends errorClass("SignatureInvalidError") {
15
- }
16
- class HexStringLengthInvalidError extends errorClass(
17
- "HexStringLengthInvalidError"
18
- ) {
19
- }
20
- class SignatureMissingError extends errorClass(
21
- "SignatureMissingError",
22
- (thirdParty) => [`"${thirdParty ? "signature" : "hash"}" parameter is missing`]
23
- ) {
24
- }
25
- class ExpiredError extends errorClassWithData(
26
- "ExpiredError",
27
- (issuedAt, expiresAt) => ({ issuedAt, expiresAt }),
28
- (issuedAt, expiresAt, now) => [
5
+ class AuthDateInvalidError extends errorClassWithData({
6
+ name: "AuthDateInvalidError",
7
+ data: (value) => ({ value }),
8
+ super: (value) => [`"auth_date" is invalid: ${value || "value is missing"}`]
9
+ }) {
10
+ }
11
+ class SignatureInvalidError extends errorClass({ name: "SignatureInvalidError" }) {
12
+ }
13
+ class HexStringLengthInvalidError extends errorClass({ name: "HexStringLengthInvalidError" }) {
14
+ }
15
+ class SignatureMissingError extends errorClass({
16
+ name: "SignatureMissingError",
17
+ super: (thirdParty) => [`"${thirdParty ? "signature" : "hash"}" parameter is missing`]
18
+ }) {
19
+ }
20
+ class ExpiredError extends errorClassWithData({
21
+ name: "ExpiredError",
22
+ data: (issuedAt, expiresAt) => ({ issuedAt, expiresAt }),
23
+ super: (issuedAt, expiresAt, now) => [
29
24
  `Init data expired. Issued at ${issuedAt.toISOString()}, expires at ${expiresAt.toISOString()}, now is ${now.toISOString()}`
30
25
  ]
31
- ) {
26
+ }) {
32
27
  }
33
28
  function hexToArrayBuffer(hexString) {
34
29
  if (hexString.length % 2 !== 0) {
35
- return E.left(new HexStringLengthInvalidError());
30
+ return either.left(new HexStringLengthInvalidError());
36
31
  }
37
32
  const buffer = new ArrayBuffer(hexString.length / 2);
38
33
  const uint8Array = new Uint8Array(buffer);
39
34
  for (let i = 0; i < hexString.length; i += 2) {
40
35
  uint8Array[i / 2] = parseInt(hexString.substring(i, i + 2), 16);
41
36
  }
42
- return E.right(buffer);
37
+ return either.right(buffer);
43
38
  }
44
39
  function arrayBufferToHex(arrBuf) {
45
40
  return new Uint8Array(arrBuf).reduce((acc, byte) => {
@@ -55,26 +50,26 @@ function hashToken(token, createHmac) {
55
50
  return createHmac(token, "WebAppData");
56
51
  }
57
52
  function signDataFp(async, data, key, createHmac, options = {}) {
58
- const keyHmac = options.tokenHashed ? typeof key === "string" ? hexToArrayBuffer(key) : E.right(key) : pipe(
59
- E.right(hashToken(key, createHmac)),
60
- E.match(() => null, (v) => {
61
- return v instanceof Promise ? TE.tryCatch(() => v, (err) => err) : E.right(v);
53
+ const keyHmac = options.tokenHashed ? typeof key === "string" ? hexToArrayBuffer(key) : either.right(key) : _function.pipe(
54
+ either.right(hashToken(key, createHmac)),
55
+ either.match(() => null, (v) => {
56
+ return v instanceof Promise ? taskEither.tryCatch(() => v, (err) => err) : either.right(v);
62
57
  })
63
58
  );
64
59
  if (async || typeof keyHmac === "function") {
65
- return pipe(
66
- typeof keyHmac === "function" ? keyHmac : TE.fromEither(keyHmac),
67
- TE.chain((v) => TE.tryCatch(
60
+ return _function.pipe(
61
+ typeof keyHmac === "function" ? keyHmac : taskEither.fromEither(keyHmac),
62
+ taskEither.chainW((v) => taskEither.tryCatch(
68
63
  () => Promise.resolve(createHmac(data, v)).then(arrayBufferToHex),
69
64
  (err) => err
70
65
  ))
71
66
  );
72
67
  }
73
- return pipe(
68
+ return _function.pipe(
74
69
  keyHmac,
75
70
  // In this branch createHmac can't be asynchronous. If it is, keyHmac would be Promise and the
76
71
  // result would be returned in the previous "if" statement.
77
- E.chain((v) => E.right(
72
+ either.chain((v) => either.right(
78
73
  arrayBufferToHex(createHmac(data, v))
79
74
  ))
80
75
  );
@@ -91,7 +86,7 @@ function signFp(data, key, authDate, signData, options) {
91
86
  return query.toString();
92
87
  };
93
88
  const eitherHash = signData(pairs.join("\n"), key, options);
94
- return typeof eitherHash === "function" ? pipe(eitherHash, TE.chain((hash) => TE.right(queryWithHash(hash)))) : pipe(eitherHash, E.chain((hash) => E.right(queryWithHash(hash))));
89
+ return typeof eitherHash === "function" ? _function.pipe(eitherHash, taskEither.chain((hash) => taskEither.right(queryWithHash(hash)))) : _function.pipe(eitherHash, either.chain((hash) => either.right(queryWithHash(hash))));
95
90
  }
96
91
  function validate3rdFp(value, botId, options = {}) {
97
92
  let authDate;
@@ -116,21 +111,21 @@ function validate3rdFp(value, botId, options = {}) {
116
111
  pairs.push(`${key}=${value2}`);
117
112
  });
118
113
  if (!signature) {
119
- return TE.left(new SignatureMissingError(true));
114
+ return taskEither.left(new SignatureMissingError(true));
120
115
  }
121
116
  if (!authDate) {
122
- return TE.left(new AuthDateInvalidError(authDateString));
117
+ return taskEither.left(new AuthDateInvalidError(authDateString));
123
118
  }
124
119
  const { expiresIn = 86400 } = options;
125
120
  if (expiresIn > 0) {
126
121
  const expiresAtTs = authDate.getTime() + expiresIn * 1e3;
127
122
  const nowTs = Date.now();
128
123
  if (expiresAtTs < nowTs) {
129
- return TE.left(new ExpiredError(authDate, new Date(expiresAtTs), new Date(nowTs)));
124
+ return taskEither.left(new ExpiredError(authDate, new Date(expiresAtTs), new Date(nowTs)));
130
125
  }
131
126
  }
132
- return pipe$1(
133
- TE.tryCatch(
127
+ return _function.pipe(
128
+ taskEither.tryCatch(
134
129
  () => {
135
130
  return BetterPromise.fn(async () => {
136
131
  return crypto.subtle.verify(
@@ -154,31 +149,31 @@ ${pairs.sort().join("\n")}`)
154
149
  },
155
150
  (e) => e
156
151
  ),
157
- TE.chainW((isVerified) => {
158
- return isVerified ? TE.right(void 0) : TE.left(new SignatureInvalidError());
152
+ taskEither.chainW((isVerified) => {
153
+ return isVerified ? taskEither.right(void 0) : taskEither.left(new SignatureInvalidError());
159
154
  })
160
155
  );
161
156
  }
162
157
  function validate3rd(value, botId, options) {
163
158
  return BetterPromise.fn(async () => {
164
- await pipe$1(
159
+ await _function.pipe(
165
160
  validate3rdFp(value, botId, options),
166
- TE.mapLeft((error) => {
161
+ taskEither.mapLeft((error) => {
167
162
  throw error;
168
163
  })
169
164
  )();
170
165
  });
171
166
  }
172
167
  function isValid3rdFp(value, botId, options) {
173
- return pipe$1(validate3rdFp(value, botId, options), TE.match(
174
- () => E.right(false),
175
- () => E.right(true)
168
+ return _function.pipe(validate3rdFp(value, botId, options), taskEither.match(
169
+ () => either.right(false),
170
+ () => either.right(true)
176
171
  ));
177
172
  }
178
173
  function isValid3rd(value, botId, options) {
179
- return BetterPromise.fn(() => pipe$1(
174
+ return BetterPromise.fn(() => _function.pipe(
180
175
  isValid3rdFp(value, botId, options),
181
- TE.match(() => false, (v) => v)
176
+ taskEither.match(() => false, (v) => v)
182
177
  )());
183
178
  }
184
179
  function validateFp(async, value, token, signData, options = {}) {
@@ -201,26 +196,26 @@ function validateFp(async, value, token, signData, options = {}) {
201
196
  pairs.push(`${key}=${value2}`);
202
197
  });
203
198
  if (!hash) {
204
- return (async ? TE.left : E.left)(new SignatureMissingError(false));
199
+ return (async ? taskEither.left : either.left)(new SignatureMissingError(false));
205
200
  }
206
201
  if (!authDate) {
207
- return (async ? TE.left : E.left)(new AuthDateInvalidError(authDateString));
202
+ return (async ? taskEither.left : either.left)(new AuthDateInvalidError(authDateString));
208
203
  }
209
204
  const { expiresIn = 86400 } = options;
210
205
  if (expiresIn > 0) {
211
206
  const expiresAtTs = authDate.getTime() + expiresIn * 1e3;
212
207
  const nowTs = Date.now();
213
208
  if (expiresAtTs < nowTs) {
214
- return (async ? TE.left : E.left)(
209
+ return (async ? taskEither.left : either.left)(
215
210
  new ExpiredError(authDate, new Date(expiresAtTs), new Date(nowTs))
216
211
  );
217
212
  }
218
213
  }
219
214
  pairs.sort();
220
215
  const eitherSignature = signData(pairs.join("\n"), token, options);
221
- const onLeft = (error) => E.left(error);
222
- const onRight = (signature) => signature === hash ? E.right(void 0) : E.left(new SignatureInvalidError());
223
- return typeof eitherSignature === "function" ? pipe$1(eitherSignature, TE.matchW(onLeft, onRight)) : pipe$1(eitherSignature, E.matchW(onLeft, onRight));
216
+ const onLeft = (error) => either.left(error);
217
+ const onRight = (signature) => signature === hash ? either.right(void 0) : either.left(new SignatureInvalidError());
218
+ return typeof eitherSignature === "function" ? _function.pipe(eitherSignature, taskEither.matchW(onLeft, onRight)) : _function.pipe(eitherSignature, either.matchW(onLeft, onRight));
224
219
  }
225
220
  const parse = parseInitDataQuery;
226
221
  const parseFp = parseInitDataQueryFp;
@@ -242,4 +237,4 @@ export {
242
237
  signFp as s,
243
238
  validateFp as v
244
239
  };
245
- //# sourceMappingURL=parsing-B9llLYuO.js.map
240
+ //# sourceMappingURL=parsing-Cn-1lfce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parsing-Cn-1lfce.js","sources":["../../src/errors.ts","../../src/buf-converters.ts","../../src/hashToken.ts","../../src/signDataFp.ts","../../src/signFp.ts","../../src/validation.ts","../../src/parsing.ts"],"sourcesContent":["import { errorClass, errorClassWithData } from 'error-kid';\n\nexport class AuthDateInvalidError extends errorClassWithData<\n { value: string | undefined },\n [value?: string]\n>({\n name: 'AuthDateInvalidError',\n data: value => ({ value }),\n super: value => [`\"auth_date\" is invalid: ${value || 'value is missing'}`],\n}) {\n}\n\nexport class SignatureInvalidError extends errorClass({ name: 'SignatureInvalidError' }) {\n}\n\nexport class HexStringLengthInvalidError extends errorClass({ name: 'HexStringLengthInvalidError' }) {\n}\n\nexport class SignatureMissingError extends errorClass<[thirdParty: boolean]>({\n name: 'SignatureMissingError',\n super: thirdParty => [`\"${thirdParty ? 'signature' : 'hash'}\" parameter is missing`],\n}) {\n}\n\nexport class ExpiredError extends errorClassWithData<\n { issuedAt: Date; expiresAt: Date },\n [issuedAt: Date, expiresAt: Date, now: Date]\n>({\n name: 'ExpiredError',\n data: (issuedAt, expiresAt) => ({ issuedAt, expiresAt }),\n super: (issuedAt, expiresAt, now) => [\n `Init data expired. Issued at ${issuedAt.toISOString()}, expires at ${expiresAt.toISOString()}, now is ${now.toISOString()}`,\n ],\n}) {\n}\n","import { either as E } from 'fp-ts';\n\nimport { HexStringLengthInvalidError } from './errors.js';\n\n/**\n * Converts a hex string to ArrayBuffer.\n * @param hexString - value to convert.\n */\nexport function hexToArrayBuffer(hexString: string): E.Either<\n InstanceType<typeof HexStringLengthInvalidError>,\n ArrayBuffer\n> {\n if (hexString.length % 2 !== 0) {\n return E.left(new HexStringLengthInvalidError());\n }\n const buffer = new ArrayBuffer(hexString.length / 2);\n const uint8Array = new Uint8Array(buffer);\n for (let i = 0; i < hexString.length; i += 2) {\n uint8Array[i / 2] = parseInt(hexString.substring(i, i + 2), 16);\n }\n return E.right(buffer);\n}\n\n/**\n * Converts array buffer to hex.\n * @param arrBuf - buffer to convert\n */\nexport function arrayBufferToHex(arrBuf: ArrayBuffer): string {\n return new Uint8Array(arrBuf).reduce((acc, byte) => {\n // Convert byte to hex and pad with zero if needed (e.g., \"0a\" instead of \"a\")\n return acc + byte.toString(16).padStart(2, '0');\n }, '');\n}\n\nexport function bufferToArrayBuffer(buf: Buffer) {\n const ab = new ArrayBuffer(buf.length);\n buf.copy(new Uint8Array(ab));\n return ab;\n}\n","import type { CreateHmacFn, Text } from './types.js';\n\nexport function hashToken<H extends CreateHmacFn<any>>(token: Text, createHmac: H): ReturnType<H> {\n return createHmac(token, 'WebAppData') as ReturnType<H>;\n}\n","import { either as E, taskEither as TE, function as fn } from 'fp-ts';\n\nimport { arrayBufferToHex, hexToArrayBuffer } from './buf-converters.js';\nimport { hashToken } from './hashToken.js';\nimport type { CreateHmacFn, Text } from './types.js';\n\nexport interface SignDataOptions {\n /**\n * True, if token is already hashed and doesn't require hashing using HMAC-SHA-256.\n */\n tokenHashed?: boolean;\n}\n\nexport type SignDataError = ReturnType<typeof hexToArrayBuffer> extends E.Either<infer U, any>\n ? U\n : never;\n\nexport function signDataFp(\n async: false,\n data: Text,\n key: Text,\n createHmac: CreateHmacFn<false>,\n options?: SignDataOptions,\n): E.Either<SignDataError, string>;\n\nexport function signDataFp(\n async: true,\n data: Text,\n key: Text,\n createHmac: CreateHmacFn<true>,\n options?: SignDataOptions,\n): TE.TaskEither<SignDataError, string>;\n\nexport function signDataFp(\n async: boolean,\n data: Text,\n key: Text,\n createHmac: CreateHmacFn<boolean>,\n options: SignDataOptions = {},\n):\n | E.Either<SignDataError, string>\n | TE.TaskEither<SignDataError, string> {\n const keyHmac = options.tokenHashed\n ? typeof key === 'string'\n // If a hashed token was passed, we assume that it is a HEX string. Not to mess with\n // the createHmac function, we should convert this HEX string to ArrayBuffer. Otherwise,\n // incorrect behavior will be met.\n ? hexToArrayBuffer(key)\n : E.right(key)\n // Otherwise we are hashing the token, but we want it to be a monad.\n : fn.pipe(\n E.right(hashToken(key, createHmac)),\n E.match(() => null as never, v => {\n return v instanceof Promise\n ? TE.tryCatch(() => v, err => err as never)\n : E.right(v);\n }),\n );\n\n if (async || typeof keyHmac === 'function') {\n return fn.pipe(\n typeof keyHmac === 'function' ? keyHmac : TE.fromEither(keyHmac),\n TE.chainW(v => TE.tryCatch(\n () => Promise.resolve(createHmac(data, v)).then(arrayBufferToHex),\n err => err as never,\n )),\n );\n }\n return fn.pipe(\n keyHmac,\n // In this branch createHmac can't be asynchronous. If it is, keyHmac would be Promise and the\n // result would be returned in the previous \"if\" statement.\n E.chain(v => E.right(\n arrayBufferToHex((createHmac as CreateHmacFn<false>)(data, v)),\n )),\n );\n}\n","import { type InitDataLike, serializeInitDataQuery } from '@tma.js/transformers';\nimport { either as E, taskEither as TE, function as fn } from 'fp-ts';\n\nimport type { Text } from './types.js';\n\nexport type SignableData =\n & Omit<InitDataLike, 'auth_date' | 'hash' | 'signature'>\n & { signature?: string };\n\nexport interface SignOptions {\n /**\n * True, if token is already hashed and doesn't require hashing using HMAC-SHA-256.\n */\n tokenHashed?: boolean;\n}\n\ninterface SignDataFpArg<Async extends boolean, Left> {\n (data: Text, key: Text, options?: SignOptions): Async extends true\n ? TE.TaskEither<Left, string>\n : E.Either<Left, string>;\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 signData - function signing data.\n * @param options - additional options.\n * @returns Signed init data presented as query parameters.\n */\nexport function signFp<Left>(\n data: SignableData,\n key: Text,\n authDate: Date,\n signData: SignDataFpArg<false, Left>,\n options?: SignOptions,\n): E.Either<Left, string>;\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 signData - function signing data.\n * @param options - additional options.\n * @returns Signed init data presented as query parameters.\n */\nexport function signFp<Left>(\n data: SignableData,\n key: Text,\n authDate: Date,\n signData: SignDataFpArg<true, Left>,\n options?: SignOptions,\n): TE.TaskEither<Left, string>;\n\nexport function signFp<Left>(\n data: SignableData,\n key: Text,\n authDate: Date,\n signData: SignDataFpArg<boolean, Left>,\n options?: SignOptions,\n): E.Either<Left, string> | TE.TaskEither<Left, string> {\n const query = new URLSearchParams(serializeInitDataQuery({\n ...data,\n auth_date: authDate,\n signature: data.signature || '',\n }));\n\n // Convert search params to pairs and sort the final array.\n const pairs = [...query.entries()]\n .map(([name, value]) => `${name}=${value}`)\n .sort();\n\n // Compute sign, append it to the params and return.\n const queryWithHash = (signature: string): string => {\n query.append('hash', signature);\n return query.toString();\n };\n\n const eitherHash = signData(pairs.join('\\n'), key, options);\n return typeof eitherHash === 'function'\n ? fn.pipe(eitherHash, TE.chain(hash => TE.right(queryWithHash(hash))))\n : fn.pipe(eitherHash, E.chain(hash => E.right(queryWithHash(hash))));\n}\n","import {\n BetterPromise,\n type BetterPromiseOptions,\n type BetterPromiseRejectReason,\n} from 'better-promises';\nimport { either as E, taskEither as TE, function as fn } from 'fp-ts';\n\nimport {\n AuthDateInvalidError,\n ExpiredError,\n SignatureInvalidError,\n SignatureMissingError,\n} from './errors.js';\nimport { Text } from './types.js';\n\ntype OmittedPromiseOptions = Omit<BetterPromiseOptions, 'abortOnResolve' | 'abortOnReject'>;\n\nexport type ValidateValue = string | URLSearchParams;\nexport type Validate3rdValue = string | URLSearchParams;\n\nexport type ValidateError =\n | SignatureMissingError\n | SignatureInvalidError\n | AuthDateInvalidError\n | ExpiredError;\nexport type ValidateAsyncError = ValidateError | BetterPromiseRejectReason;\nexport type Validate3rdError =\n | SignatureMissingError\n | SignatureInvalidError\n | AuthDateInvalidError\n | ExpiredError\n | BetterPromiseRejectReason;\n\ninterface ValidateSignDataFpArg<Async extends boolean, Left> {\n (data: Text, key: Text, options?: ValidateOptions): Async extends true\n ? TE.TaskEither<Left, string>\n : E.Either<Left, string>;\n}\n\ninterface SharedValidateOptions {\n /**\n * Time in seconds which states, how long from creation time init data is considered valid.\n *\n * In other words, in case when authDate + expiresIn is before current time, init data is\n * recognized as expired.\n *\n * In case this value is equal to 0, the function does not check init data expiration.\n * @default 86400 (1 day)\n */\n expiresIn?: number;\n}\n\nexport interface ValidateOptions extends SharedValidateOptions {\n /**\n * True, if token is already hashed.\n * @default false\n */\n tokenHashed?: boolean;\n}\n\nexport interface ValidateAsyncOptions extends ValidateOptions, OmittedPromiseOptions {\n}\n\nexport interface Validate3rdOptions extends SharedValidateOptions, OmittedPromiseOptions {\n /**\n * When true, uses the test environment public key to validate init data.\n * @default false\n */\n test?: boolean;\n}\n\n/**\n * Validates passed init data using a publicly known Ee25519 key.\n * @param value - value to check.\n * @param botId - bot identifier\n * @param options - additional validation options.\n */\nexport function validate3rdFp(\n value: Validate3rdValue,\n botId: number,\n options: Validate3rdOptions = {},\n): TE.TaskEither<Validate3rdError, void> {\n // Init data required params.\n let authDate: Date | undefined;\n let authDateString: string | undefined;\n let signature: string | undefined;\n\n // All search params pairs presented as `k=v`.\n const pairs: string[] = [];\n\n // Iterate over all key-value pairs of parsed parameters and find required\n // parameters.\n (typeof value === 'string' ? new URLSearchParams(value) : value).forEach((value, key) => {\n if (key === 'hash') {\n return;\n }\n if (key === 'signature') {\n signature = value;\n return;\n }\n if (key === 'auth_date') {\n authDateString = value;\n const authDateNum = parseInt(value, 10);\n if (!Number.isNaN(authDateNum)) {\n authDate = new Date(authDateNum * 1000);\n }\n }\n\n pairs.push(`${key}=${value}`);\n });\n\n // Signature and auth date always required.\n if (!signature) {\n return TE.left(new SignatureMissingError(true));\n }\n\n if (!authDate) {\n return TE.left(new AuthDateInvalidError(authDateString));\n }\n\n // In case, expiration time passed, we do additional parameters check.\n const { expiresIn = 86400 } = options;\n if (expiresIn > 0) {\n // Check if init data expired.\n const expiresAtTs = authDate.getTime() + (expiresIn * 1000);\n const nowTs = Date.now();\n if (expiresAtTs < nowTs) {\n return TE.left(new ExpiredError(authDate, new Date(expiresAtTs), new Date(nowTs)));\n }\n }\n\n return fn.pipe(\n TE.tryCatch(\n () => {\n return BetterPromise.fn(async () => {\n return crypto.subtle.verify(\n 'Ed25519',\n await crypto.subtle.importKey(\n 'raw',\n Buffer.from(\n options.test\n ? '40055058a4ee38156a06562e52eece92a771bcd8346a8c4615cb7376eddf72ec'\n : 'e7bf03a2fa4602af4580703d88dda5bb59f32ed8b02a56c187fe7d34caed242d',\n 'hex',\n ),\n 'Ed25519',\n false,\n ['verify'],\n ),\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n Buffer.from(signature as string, 'base64'),\n Buffer.from(`${botId}:WebAppData\\n${pairs.sort().join('\\n')}`),\n );\n }, options);\n },\n (e: unknown) => e,\n ),\n TE.chainW(isVerified => {\n return isVerified\n ? TE.right(undefined)\n : TE.left(new SignatureInvalidError());\n }),\n );\n}\n\n/**\n * @see validate3rdFp\n */\nexport function validate3rd(\n value: Validate3rdValue,\n botId: number,\n options?: Validate3rdOptions,\n): BetterPromise<void> {\n return BetterPromise.fn(async () => {\n await fn.pipe(\n validate3rdFp(value, botId, options),\n TE.mapLeft(error => {\n throw error;\n }),\n )();\n });\n}\n\n/**\n * @param value - value to check.\n * @param botId - bot identifier\n * @param options - additional validation options.\n * @returns True is specified init data is signed by Telegram.\n */\nexport function isValid3rdFp(\n value: Validate3rdValue,\n botId: number,\n options?: Validate3rdOptions,\n): TE.TaskEither<void, boolean> {\n return fn.pipe(validate3rdFp(value, botId, options), TE.match(\n () => E.right(false),\n () => E.right(true),\n ));\n}\n\n/**\n * @see isValid3rdFp\n */\nexport function isValid3rd(\n value: Validate3rdValue,\n botId: number,\n options?: Validate3rdOptions,\n): BetterPromise<boolean> {\n return BetterPromise.fn(() => fn.pipe(\n isValid3rdFp(value, botId, options),\n TE.match(() => false, v => v),\n )());\n}\n\nexport function validateFp<Left>(\n async: false,\n value: ValidateValue,\n token: Text,\n signData: ValidateSignDataFpArg<false, Left>,\n options?: ValidateOptions,\n): E.Either<Left | ValidateError, void>;\n\nexport function validateFp<Left>(\n async: true,\n value: ValidateValue,\n token: Text,\n signData: ValidateSignDataFpArg<true, Left>,\n options?: ValidateAsyncOptions,\n): TE.TaskEither<Left | ValidateAsyncError, void>;\n\nexport function validateFp<Left>(\n async: boolean,\n value: ValidateValue,\n token: Text,\n signData: ValidateSignDataFpArg<boolean, Left>,\n options: ValidateOptions | ValidateAsyncOptions = {},\n):\n | E.Either<Left | ValidateError, void>\n | TE.TaskEither<Left | ValidateAsyncError, void> {\n // Init data required params.\n let authDate: Date | undefined;\n let authDateString: string | undefined;\n let hash: string | undefined;\n\n // All search params pairs presented as `k=v`.\n const pairs: string[] = [];\n\n // Iterate over all key-value pairs of parsed parameters and find required\n // parameters.\n (typeof value === 'string' ? new URLSearchParams(value) : value).forEach((value, key) => {\n if (key === 'hash') {\n hash = value;\n return;\n }\n\n if (key === 'auth_date') {\n authDateString = value;\n const authDateNum = parseInt(value, 10);\n if (!Number.isNaN(authDateNum)) {\n authDate = new Date(authDateNum * 1000);\n }\n }\n\n pairs.push(`${key}=${value}`);\n });\n\n // Hash and auth date always required.\n if (!hash) {\n return (async ? TE.left : E.left)(new SignatureMissingError(false));\n }\n\n if (!authDate) {\n return (async ? TE.left : E.left)(new AuthDateInvalidError(authDateString));\n }\n\n // In case, expiration time passed, we do additional parameters check.\n const { expiresIn = 86400 } = options;\n if (expiresIn > 0) {\n // Check if init data expired.\n const expiresAtTs = authDate.getTime() + (expiresIn * 1000);\n const nowTs = Date.now();\n if (expiresAtTs < nowTs) {\n return (async ? TE.left : E.left)(\n new ExpiredError(authDate, new Date(expiresAtTs), new Date(nowTs)),\n );\n }\n }\n\n // According to docs, we sort all the pairs in alphabetical order.\n pairs.sort();\n\n const eitherSignature = signData(pairs.join('\\n'), token, options);\n const onLeft = (error: Left) => E.left(error);\n const onRight = (signature: string) => (\n signature === hash ? E.right(undefined) : E.left(new SignatureInvalidError())\n );\n\n return typeof eitherSignature === 'function'\n ? fn.pipe(eitherSignature, TE.matchW(onLeft, onRight))\n : fn.pipe(eitherSignature, E.matchW(onLeft, onRight));\n}\n","import {\n parseInitDataQuery,\n parseInitDataQueryFp,\n type ParseInitDataQueryError,\n} from '@tma.js/transformers';\n\n/**\n * Parses an incoming value as init data.\n */\nexport const parse = parseInitDataQuery;\n\n/**\n * Parses an incoming value as init data.\n */\nexport const parseFp = parseInitDataQueryFp;\n\nexport { ParseInitDataQueryError as ParseError };\n"],"names":["E","fn","TE","value"],"mappings":"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"}
@@ -1,29 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const betterPromises = require("better-promises");
4
- const E = require("fp-ts/Either");
5
- const TE = require("fp-ts/TaskEither");
6
- const function_js = require("fp-ts/lib/function.js");
7
- const parsing = require("./parsing-pEQ1lsuE.cjs");
4
+ const fpTs = require("fp-ts");
5
+ const parsing = require("./parsing-BMJa8cb6.cjs");
8
6
  const toolkit = require("@tma.js/toolkit");
9
- function _interopNamespaceDefault(e) {
10
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
11
- if (e) {
12
- for (const k in e) {
13
- if (k !== "default") {
14
- const d = Object.getOwnPropertyDescriptor(e, k);
15
- Object.defineProperty(n, k, d.get ? d : {
16
- enumerable: true,
17
- get: () => e[k]
18
- });
19
- }
20
- }
21
- }
22
- n.default = e;
23
- return Object.freeze(n);
24
- }
25
- const E__namespace = /* @__PURE__ */ _interopNamespaceDefault(E);
26
- const TE__namespace = /* @__PURE__ */ _interopNamespaceDefault(TE);
27
7
  const createHmac = async (data, key) => {
28
8
  const encoder = new TextEncoder();
29
9
  return crypto.subtle.sign(
@@ -42,9 +22,9 @@ function hashToken(token) {
42
22
  return parsing.hashToken(token, createHmac);
43
23
  }
44
24
  function isValidFp(value, token, options) {
45
- return function_js.pipe(
25
+ return fpTs.function.pipe(
46
26
  validateFp(value, token, options),
47
- TE__namespace.match(
27
+ fpTs.taskEither.match(
48
28
  (error) => {
49
29
  return [
50
30
  parsing.AuthDateInvalidError,
@@ -52,17 +32,17 @@ function isValidFp(value, token, options) {
52
32
  parsing.SignatureInvalidError,
53
33
  parsing.SignatureMissingError,
54
34
  parsing.HexStringLengthInvalidError
55
- ].some((errorClass) => errorClass.is(error)) ? E__namespace.right(false) : E__namespace.left(error);
35
+ ].some((errorClass) => errorClass.is(error)) ? fpTs.either.right(false) : fpTs.either.left(error);
56
36
  },
57
- () => E__namespace.right(true)
37
+ () => fpTs.either.right(true)
58
38
  )
59
39
  );
60
40
  }
61
41
  function isValid(value, token, options) {
62
42
  return betterPromises.BetterPromise.fn(() => {
63
- return function_js.pipe(
43
+ return fpTs.function.pipe(
64
44
  isValidFp(value, token, options),
65
- TE__namespace.match((error) => {
45
+ fpTs.taskEither.match((error) => {
66
46
  throw error;
67
47
  }, (isValid2) => isValid2)
68
48
  )();
@@ -73,9 +53,9 @@ function signFp(data, key, authDate, options) {
73
53
  }
74
54
  function sign(data, key, authDate, options) {
75
55
  return betterPromises.BetterPromise.fn(() => {
76
- return function_js.pipe(
56
+ return fpTs.function.pipe(
77
57
  signFp(data, key, authDate, options),
78
- TE__namespace.match((e) => {
58
+ fpTs.taskEither.match((e) => {
79
59
  throw e;
80
60
  }, (v) => v)
81
61
  )();
@@ -86,9 +66,9 @@ function signDataFp(data, key, options) {
86
66
  }
87
67
  function signData(data, key, options) {
88
68
  return betterPromises.BetterPromise.fn(() => {
89
- return function_js.pipe(
69
+ return fpTs.function.pipe(
90
70
  signDataFp(data, key, options),
91
- TE__namespace.match((e) => {
71
+ fpTs.taskEither.match((e) => {
92
72
  throw e;
93
73
  }, (v) => v)
94
74
  )();
@@ -99,9 +79,9 @@ function validateFp(value, token, options) {
99
79
  }
100
80
  function validate(value, token, options) {
101
81
  return betterPromises.BetterPromise.fn(async () => {
102
- await function_js.pipe(
82
+ await fpTs.function.pipe(
103
83
  validateFp(value, token, options),
104
- TE__namespace.mapLeft((error) => {
84
+ fpTs.taskEither.mapLeft((error) => {
105
85
  throw error;
106
86
  })
107
87
  )();
@@ -1 +1 @@
1
- {"version":3,"file":"web.cjs","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 {\n AuthDateInvalidError,\n ExpiredError,\n SignatureInvalidError,\n SignatureMissingError,\n HexStringLengthInvalidError,\n} from '../errors.js';\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';\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","pipe","TE","AuthDateInvalidError","ExpiredError","SignatureInvalidError","SignatureMissingError","HexStringLengthInvalidError","E","BetterPromise","isValid","_signFp","_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,QAAA,UAAW,OAAO,UAAU;AACrC;AAQgB,SAAA,UACd,OACA,OACA,SACmD;AAC5C,SAAAC,YAAA;AAAA,IACL,WAAW,OAAO,OAAO,OAAO;AAAA,IAChCC,cAAG;AAAA,MACD,CAAS,UAAA;AACA,eAAA;AAAA,UACLC,QAAA;AAAA,UACAC,QAAA;AAAA,UACAC,QAAA;AAAA,UACAC,QAAA;AAAA,UACAC,QAAAA;AAAAA,QACA,EAAA,KAAK,CAAc,eAAA,WAAW,GAAG,KAAK,CAAC,IACrCC,aAAE,MAAM,KAAK,IACbA,aAAE,KAAK,KAAK;AAAA,MAClB;AAAA,MACA,MAAMA,aAAE,MAAM,IAAI;AAAA,IAAA;AAAA,EAEtB;AACF;AAKgB,SAAA,QACd,OACA,OACA,SACwB;AACjB,SAAAC,eAAAA,cAAc,GAAG,MAAM;AACrB,WAAAR,YAAA;AAAA,MACL,UAAU,OAAO,OAAO,OAAO;AAAA,MAC/BC,cAAG,MAAM,CAAS,UAAA;AACV,cAAA;AAAA,MAAA,GACL,CAAAQ,aAAWA,QAAO;AAAA,IAAA,EACrB;AAAA,EAAA,CACH;AACH;AAUO,SAAS,OACd,MACA,KACA,UACA,SACsC;AACtC,SAAOC,QAAAA,OAAQ,MAAM,KAAK,UAAU,YAAY,OAAO;AACzD;AAKO,SAAS,KACd,MACA,KACA,UACA,SACuB;AAChB,SAAAF,eAAAA,cAAc,GAAG,MAAM;AACrB,WAAAR,YAAA;AAAA,MACL,OAAO,MAAM,KAAK,UAAU,OAAO;AAAA,MACnCC,cAAG,MAAM,CAAK,MAAA;AACN,cAAA;AAAA,MAAA,GACL,OAAK,CAAC;AAAA,IAAA,EACT;AAAA,EAAA,CACH;AACH;AASgB,SAAA,WACd,MACA,KACA,SACsC;AACtC,SAAOU,QAAAA,WAAY,MAAM,MAAM,KAAK,YAAY,OAAO;AACzD;AAKgB,SAAA,SAAS,MAAY,KAAW,SAAkD;AACzF,SAAAH,eAAAA,cAAc,GAAG,MAAM;AACrB,WAAAR,YAAA;AAAA,MACL,WAAW,MAAM,KAAK,OAAO;AAAA,MAC7BC,cAAG,MAAM,CAAK,MAAA;AACN,cAAA;AAAA,MAAA,GACL,OAAK,CAAC;AAAA,IAAA,EACT;AAAA,EAAA,CACH;AACH;AAQgB,SAAA,WACd,OACA,OACA,SACyC;AACzC,SAAOW,QAAAA,WAAY,MAAM,OAAO,OAAO,YAAY,OAAO;AAC5D;AAKgB,SAAA,SACd,OACA,OACA,SACqB;AACd,SAAAJ,eAAAA,cAAc,GAAG,YAAY;AAC5B,UAAAR,YAAA;AAAA,MACJ,WAAW,OAAO,OAAO,OAAO;AAAA,MAChCC,cAAG,QAAQ,CAAS,UAAA;AACZ,cAAA;AAAA,MACP,CAAA;AAAA,IAAA,EACD;AAAA,EAAA,CACH;AACH;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"web.cjs","sources":["../../src/entries/web.ts"],"sourcesContent":["import { BetterPromise, type BetterPromiseRejectReason } from 'better-promises';\nimport { function as fn, either as E, taskEither as TE } from 'fp-ts';\n\nimport {\n AuthDateInvalidError,\n ExpiredError,\n SignatureInvalidError,\n SignatureMissingError,\n HexStringLengthInvalidError,\n} from '../errors.js';\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';\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 fn.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 fn.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 fn.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 fn.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 fn.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","fn","TE","AuthDateInvalidError","ExpiredError","SignatureInvalidError","SignatureMissingError","HexStringLengthInvalidError","E","BetterPromise","isValid","_signFp","_signDataFp","_validateFp"],"mappings":";;;;;;AAyBA,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,QAAA,UAAW,OAAO,UAAU;AACrC;AAQgB,SAAA,UACd,OACA,OACA,SACmD;AACnD,SAAOC,KAAG,SAAA;AAAA,IACR,WAAW,OAAO,OAAO,OAAO;AAAA,IAChCC,KAAAA,WAAG;AAAA,MACD,CAAS,UAAA;AACA,eAAA;AAAA,UACLC,QAAA;AAAA,UACAC,QAAA;AAAA,UACAC,QAAA;AAAA,UACAC,QAAA;AAAA,UACAC,QAAAA;AAAAA,QACA,EAAA,KAAK,CAAc,eAAA,WAAW,GAAG,KAAK,CAAC,IACrCC,KAAA,OAAE,MAAM,KAAK,IACbA,KAAAA,OAAE,KAAK,KAAK;AAAA,MAClB;AAAA,MACA,MAAMA,KAAAA,OAAE,MAAM,IAAI;AAAA,IAAA;AAAA,EAEtB;AACF;AAKgB,SAAA,QACd,OACA,OACA,SACwB;AACjB,SAAAC,eAAAA,cAAc,GAAG,MAAM;AAC5B,WAAOR,KAAG,SAAA;AAAA,MACR,UAAU,OAAO,OAAO,OAAO;AAAA,MAC/BC,gBAAG,MAAM,CAAS,UAAA;AACV,cAAA;AAAA,MAAA,GACL,CAAAQ,aAAWA,QAAO;AAAA,IAAA,EACrB;AAAA,EAAA,CACH;AACH;AAUO,SAAS,OACd,MACA,KACA,UACA,SACsC;AACtC,SAAOC,QAAAA,OAAQ,MAAM,KAAK,UAAU,YAAY,OAAO;AACzD;AAKO,SAAS,KACd,MACA,KACA,UACA,SACuB;AAChB,SAAAF,eAAAA,cAAc,GAAG,MAAM;AAC5B,WAAOR,KAAG,SAAA;AAAA,MACR,OAAO,MAAM,KAAK,UAAU,OAAO;AAAA,MACnCC,gBAAG,MAAM,CAAK,MAAA;AACN,cAAA;AAAA,MAAA,GACL,OAAK,CAAC;AAAA,IAAA,EACT;AAAA,EAAA,CACH;AACH;AASgB,SAAA,WACd,MACA,KACA,SACsC;AACtC,SAAOU,QAAAA,WAAY,MAAM,MAAM,KAAK,YAAY,OAAO;AACzD;AAKgB,SAAA,SAAS,MAAY,KAAW,SAAkD;AACzF,SAAAH,eAAAA,cAAc,GAAG,MAAM;AAC5B,WAAOR,KAAG,SAAA;AAAA,MACR,WAAW,MAAM,KAAK,OAAO;AAAA,MAC7BC,gBAAG,MAAM,CAAK,MAAA;AACN,cAAA;AAAA,MAAA,GACL,OAAK,CAAC;AAAA,IAAA,EACT;AAAA,EAAA,CACH;AACH;AAQgB,SAAA,WACd,OACA,OACA,SACyC;AACzC,SAAOW,QAAAA,WAAY,MAAM,OAAO,OAAO,YAAY,OAAO;AAC5D;AAKgB,SAAA,SACd,OACA,OACA,SACqB;AACd,SAAAJ,eAAAA,cAAc,GAAG,YAAY;AAClC,UAAMR,KAAG,SAAA;AAAA,MACP,WAAW,OAAO,OAAO,OAAO;AAAA,MAChCC,gBAAG,QAAQ,CAAS,UAAA;AACZ,cAAA;AAAA,MACP,CAAA;AAAA,IAAA,EACD;AAAA,EAAA,CACH;AACH;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,9 +1,9 @@
1
1
  import { BetterPromise, BetterPromiseRejectReason } from 'better-promises';
2
+ import { taskEither as TE } from 'fp-ts';
2
3
  import { SignDataError, SignDataOptions } from '../signDataFp.js';
3
4
  import { SignableData, SignOptions } from '../signFp.js';
4
5
  import { Text } from '../types.js';
5
6
  import { ValidateValue, ValidateAsyncError, ValidateAsyncOptions } from '../validation.js';
6
- import * as TE from 'fp-ts/TaskEither';
7
7
  /**
8
8
  * Hashes specified token using a string, expected during init data sign.
9
9
  * @param token - token to hash.
@@ -1,9 +1,7 @@
1
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-B9llLYuO.js";
6
- import { i, e, p, d, f, g } from "./parsing-B9llLYuO.js";
2
+ import { function as _function, taskEither, either } from "fp-ts";
3
+ 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-Cn-1lfce.js";
4
+ import { i, e, p, d, f, g } from "./parsing-Cn-1lfce.js";
7
5
  import { deepSnakeToCamelObjKeys } from "@tma.js/toolkit";
8
6
  const createHmac = async (data, key) => {
9
7
  const encoder = new TextEncoder();
@@ -23,9 +21,9 @@ function hashToken(token) {
23
21
  return hashToken$1(token, createHmac);
24
22
  }
25
23
  function isValidFp(value, token, options) {
26
- return pipe(
24
+ return _function.pipe(
27
25
  validateFp(value, token, options),
28
- TE.match(
26
+ taskEither.match(
29
27
  (error) => {
30
28
  return [
31
29
  AuthDateInvalidError,
@@ -33,17 +31,17 @@ function isValidFp(value, token, options) {
33
31
  SignatureInvalidError,
34
32
  SignatureMissingError,
35
33
  HexStringLengthInvalidError
36
- ].some((errorClass) => errorClass.is(error)) ? E.right(false) : E.left(error);
34
+ ].some((errorClass) => errorClass.is(error)) ? either.right(false) : either.left(error);
37
35
  },
38
- () => E.right(true)
36
+ () => either.right(true)
39
37
  )
40
38
  );
41
39
  }
42
40
  function isValid(value, token, options) {
43
41
  return BetterPromise.fn(() => {
44
- return pipe(
42
+ return _function.pipe(
45
43
  isValidFp(value, token, options),
46
- TE.match((error) => {
44
+ taskEither.match((error) => {
47
45
  throw error;
48
46
  }, (isValid2) => isValid2)
49
47
  )();
@@ -54,9 +52,9 @@ function signFp(data, key, authDate, options) {
54
52
  }
55
53
  function sign(data, key, authDate, options) {
56
54
  return BetterPromise.fn(() => {
57
- return pipe(
55
+ return _function.pipe(
58
56
  signFp(data, key, authDate, options),
59
- TE.match((e2) => {
57
+ taskEither.match((e2) => {
60
58
  throw e2;
61
59
  }, (v) => v)
62
60
  )();
@@ -67,9 +65,9 @@ function signDataFp(data, key, options) {
67
65
  }
68
66
  function signData(data, key, options) {
69
67
  return BetterPromise.fn(() => {
70
- return pipe(
68
+ return _function.pipe(
71
69
  signDataFp(data, key, options),
72
- TE.match((e2) => {
70
+ taskEither.match((e2) => {
73
71
  throw e2;
74
72
  }, (v) => v)
75
73
  )();
@@ -80,9 +78,9 @@ function validateFp(value, token, options) {
80
78
  }
81
79
  function validate(value, token, options) {
82
80
  return BetterPromise.fn(async () => {
83
- await pipe(
81
+ await _function.pipe(
84
82
  validateFp(value, token, options),
85
- TE.mapLeft((error) => {
83
+ taskEither.mapLeft((error) => {
86
84
  throw error;
87
85
  })
88
86
  )();
@@ -1 +1 @@
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 {\n AuthDateInvalidError,\n ExpiredError,\n SignatureInvalidError,\n SignatureMissingError,\n HexStringLengthInvalidError,\n} from '../errors.js';\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';\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;"}
1
+ {"version":3,"file":"web.js","sources":["../../src/entries/web.ts"],"sourcesContent":["import { BetterPromise, type BetterPromiseRejectReason } from 'better-promises';\nimport { function as fn, either as E, taskEither as TE } from 'fp-ts';\n\nimport {\n AuthDateInvalidError,\n ExpiredError,\n SignatureInvalidError,\n SignatureMissingError,\n HexStringLengthInvalidError,\n} from '../errors.js';\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';\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 fn.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 fn.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 fn.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 fn.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 fn.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","fn","TE","E","isValid","_signFp","e","_signDataFp","_validateFp"],"mappings":";;;;;AAyBA,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;AACnD,SAAOC,UAAG;AAAA,IACR,WAAW,OAAO,OAAO,OAAO;AAAA,IAChCC,WAAG;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,IACrCC,OAAE,MAAM,KAAK,IACbA,OAAE,KAAK,KAAK;AAAA,MAClB;AAAA,MACA,MAAMA,OAAE,MAAM,IAAI;AAAA,IAAA;AAAA,EAEtB;AACF;AAKgB,SAAA,QACd,OACA,OACA,SACwB;AACjB,SAAA,cAAc,GAAG,MAAM;AAC5B,WAAOF,UAAG;AAAA,MACR,UAAU,OAAO,OAAO,OAAO;AAAA,MAC/BC,WAAG,MAAM,CAAS,UAAA;AACV,cAAA;AAAA,MAAA,GACL,CAAAE,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;AAC5B,WAAOJ,UAAG;AAAA,MACR,OAAO,MAAM,KAAK,UAAU,OAAO;AAAA,MACnCC,WAAG,MAAM,CAAKI,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;AAC5B,WAAON,UAAG;AAAA,MACR,WAAW,MAAM,KAAK,OAAO;AAAA,MAC7BC,WAAG,MAAM,CAAKI,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;AAClC,UAAMP,UAAG;AAAA,MACP,WAAW,OAAO,OAAO,OAAO;AAAA,MAChCC,WAAG,QAAQ,CAAS,UAAA;AACZ,cAAA;AAAA,MACP,CAAA;AAAA,IAAA,EACD;AAAA,EAAA,CACH;AACH;"}
@@ -1,7 +1,6 @@
1
+ import { either as E, taskEither as TE } from 'fp-ts';
1
2
  import { hexToArrayBuffer } from './buf-converters.js';
2
3
  import { CreateHmacFn, Text } from './types.js';
3
- import * as E from 'fp-ts/Either';
4
- import * as TE from 'fp-ts/TaskEither';
5
4
  export interface SignDataOptions {
6
5
  /**
7
6
  * True, if token is already hashed and doesn't require hashing using HMAC-SHA-256.
package/dist/signFp.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { InitDataLike } from '@tma.js/transformers';
2
+ import { either as E, taskEither as TE } from 'fp-ts';
2
3
  import { Text } from './types.js';
3
- import * as E from 'fp-ts/Either';
4
- import * as TE from 'fp-ts/TaskEither';
5
4
  export type SignableData = Omit<InitDataLike, 'auth_date' | 'hash' | 'signature'> & {
6
5
  signature?: string;
7
6
  };
@@ -1,8 +1,7 @@
1
1
  import { BetterPromise, BetterPromiseOptions, BetterPromiseRejectReason } from 'better-promises';
2
+ import { either as E, taskEither as TE } from 'fp-ts';
2
3
  import { AuthDateInvalidError, ExpiredError, SignatureInvalidError, SignatureMissingError } from './errors.js';
3
4
  import { Text } from './types.js';
4
- import * as E from 'fp-ts/Either';
5
- import * as TE from 'fp-ts/TaskEither';
6
5
  type OmittedPromiseOptions = Omit<BetterPromiseOptions, 'abortOnResolve' | 'abortOnReject'>;
7
6
  export type ValidateValue = string | URLSearchParams;
8
7
  export type Validate3rdValue = string | URLSearchParams;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tma.js/init-data-node",
3
- "version": "2.0.5",
3
+ "version": "2.0.7",
4
4
  "description": "TypeScript Node library to operate with Telegram init data.",
5
5
  "author": "Vladislav Kibenko <wolfram.deus@gmail.com>",
6
6
  "homepage": "https://github.com/Telegram-Mini-Apps/tma.js#readme",
@@ -51,10 +51,10 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "better-promises": "^1.0.0",
54
- "error-kid": "^1.0.2",
54
+ "error-kid": "^2.0.0",
55
55
  "fp-ts": "^2.16.11",
56
- "@tma.js/toolkit": "^1.0.3",
57
- "@tma.js/transformers": "^1.1.2",
56
+ "@tma.js/toolkit": "^1.0.4",
57
+ "@tma.js/transformers": "^1.1.3",
58
58
  "@tma.js/types": "^1.0.2"
59
59
  },
60
60
  "scripts": {
@@ -1 +0,0 @@
1
- {"version":3,"file":"parsing-B9llLYuO.js","sources":["../../src/errors.ts","../../src/buf-converters.ts","../../src/hashToken.ts","../../src/signDataFp.ts","../../src/signFp.ts","../../src/validation.ts","../../src/parsing.ts"],"sourcesContent":["import { errorClass, errorClassWithData } from 'error-kid';\n\nexport class AuthDateInvalidError extends errorClassWithData<\n { value: string | undefined },\n [value?: string]\n>(\n 'AuthDateInvalidError',\n value => ({ value }),\n value => [`\"auth_date\" is invalid: ${value || 'value is missing'}`],\n) {\n}\n\nexport class SignatureInvalidError extends errorClass('SignatureInvalidError') {\n}\n\nexport class HexStringLengthInvalidError extends errorClass(\n 'HexStringLengthInvalidError',\n) {\n}\n\nexport class SignatureMissingError extends errorClass<[thirdParty: boolean]>(\n 'SignatureMissingError',\n thirdParty => [`\"${thirdParty ? 'signature' : 'hash'}\" parameter is missing`],\n) {\n}\n\nexport class ExpiredError extends errorClassWithData<\n { issuedAt: Date; expiresAt: Date },\n [issuedAt: Date, expiresAt: Date, now: Date]\n>(\n 'ExpiredError',\n (issuedAt, expiresAt) => ({ issuedAt, expiresAt }),\n (issuedAt, expiresAt, now) => [\n `Init data expired. Issued at ${issuedAt.toISOString()}, expires at ${expiresAt.toISOString()}, now is ${now.toISOString()}`,\n ],\n) {\n}\n","import * as E from 'fp-ts/Either';\n\nimport { HexStringLengthInvalidError } from './errors.js';\n\n/**\n * Converts a hex string to ArrayBuffer.\n * @param hexString - value to convert.\n */\nexport function hexToArrayBuffer(hexString: string): E.Either<\n InstanceType<typeof HexStringLengthInvalidError>,\n ArrayBuffer\n> {\n if (hexString.length % 2 !== 0) {\n return E.left(new HexStringLengthInvalidError());\n }\n const buffer = new ArrayBuffer(hexString.length / 2);\n const uint8Array = new Uint8Array(buffer);\n for (let i = 0; i < hexString.length; i += 2) {\n uint8Array[i / 2] = parseInt(hexString.substring(i, i + 2), 16);\n }\n return E.right(buffer);\n}\n\n/**\n * Converts array buffer to hex.\n * @param arrBuf - buffer to convert\n */\nexport function arrayBufferToHex(arrBuf: ArrayBuffer): string {\n return new Uint8Array(arrBuf).reduce((acc, byte) => {\n // Convert byte to hex and pad with zero if needed (e.g., \"0a\" instead of \"a\")\n return acc + byte.toString(16).padStart(2, '0');\n }, '');\n}\n\nexport function bufferToArrayBuffer(buf: Buffer) {\n const ab = new ArrayBuffer(buf.length);\n buf.copy(new Uint8Array(ab));\n return ab;\n}\n","import type { CreateHmacFn, Text } from './types.js';\n\nexport function hashToken<H extends CreateHmacFn<any>>(token: Text, createHmac: H): ReturnType<H> {\n return createHmac(token, 'WebAppData') as ReturnType<H>;\n}\n","import * as E from 'fp-ts/Either';\nimport * as TE from 'fp-ts/TaskEither';\nimport { pipe } from 'fp-ts/lib/function.js';\n\nimport { arrayBufferToHex, hexToArrayBuffer } from './buf-converters.js';\nimport { hashToken } from './hashToken.js';\nimport type { CreateHmacFn, Text } from './types.js';\n\nexport interface SignDataOptions {\n /**\n * True, if token is already hashed and doesn't require hashing using HMAC-SHA-256.\n */\n tokenHashed?: boolean;\n}\n\nexport type SignDataError = ReturnType<typeof hexToArrayBuffer> extends E.Either<infer U, any>\n ? U\n : never;\n\nexport function signDataFp(\n async: false,\n data: Text,\n key: Text,\n createHmac: CreateHmacFn<false>,\n options?: SignDataOptions,\n): E.Either<SignDataError, string>;\n\nexport function signDataFp(\n async: true,\n data: Text,\n key: Text,\n createHmac: CreateHmacFn<true>,\n options?: SignDataOptions,\n): TE.TaskEither<SignDataError, string>;\n\nexport function signDataFp(\n async: boolean,\n data: Text,\n key: Text,\n createHmac: CreateHmacFn<boolean>,\n options: SignDataOptions = {},\n):\n | E.Either<SignDataError, string>\n | TE.TaskEither<SignDataError, string> {\n const keyHmac = options.tokenHashed\n ? typeof key === 'string'\n // If a hashed token was passed, we assume that it is a HEX string. Not to mess with\n // the createHmac function, we should convert this HEX string to ArrayBuffer. Otherwise,\n // incorrect behavior will be met.\n ? hexToArrayBuffer(key)\n : E.right(key)\n // Otherwise we are hashing the token, but we want it to be a monad.\n : pipe(\n E.right(hashToken(key, createHmac)),\n E.match(() => null as never, v => {\n return v instanceof Promise\n ? TE.tryCatch(() => v, err => err as SignDataError)\n : E.right(v);\n }),\n );\n\n if (async || typeof keyHmac === 'function') {\n return pipe(\n typeof keyHmac === 'function' ? keyHmac : TE.fromEither(keyHmac),\n TE.chain(v => TE.tryCatch(\n () => Promise.resolve(createHmac(data, v)).then(arrayBufferToHex),\n err => err as SignDataError,\n )),\n );\n }\n return pipe(\n keyHmac,\n // In this branch createHmac can't be asynchronous. If it is, keyHmac would be Promise and the\n // result would be returned in the previous \"if\" statement.\n E.chain(v => E.right(\n arrayBufferToHex((createHmac as CreateHmacFn<false>)(data, v)),\n )),\n );\n}\n","import { type InitDataLike, serializeInitDataQuery } from '@tma.js/transformers';\nimport * as E from 'fp-ts/Either';\nimport * as TE from 'fp-ts/TaskEither';\nimport { pipe } from 'fp-ts/lib/function.js';\n\nimport type { Text } from './types.js';\n\nexport type SignableData =\n & Omit<InitDataLike, 'auth_date' | 'hash' | 'signature'>\n & { signature?: string };\n\nexport interface SignOptions {\n /**\n * True, if token is already hashed and doesn't require hashing using HMAC-SHA-256.\n */\n tokenHashed?: boolean;\n}\n\ninterface SignDataFpArg<Async extends boolean, Left> {\n (data: Text, key: Text, options?: SignOptions): Async extends true\n ? TE.TaskEither<Left, string>\n : E.Either<Left, string>;\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 signData - function signing data.\n * @param options - additional options.\n * @returns Signed init data presented as query parameters.\n */\nexport function signFp<Left>(\n data: SignableData,\n key: Text,\n authDate: Date,\n signData: SignDataFpArg<false, Left>,\n options?: SignOptions,\n): E.Either<Left, string>;\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 signData - function signing data.\n * @param options - additional options.\n * @returns Signed init data presented as query parameters.\n */\nexport function signFp<Left>(\n data: SignableData,\n key: Text,\n authDate: Date,\n signData: SignDataFpArg<true, Left>,\n options?: SignOptions,\n): TE.TaskEither<Left, string>;\n\nexport function signFp<Left>(\n data: SignableData,\n key: Text,\n authDate: Date,\n signData: SignDataFpArg<boolean, Left>,\n options?: SignOptions,\n): E.Either<Left, string> | TE.TaskEither<Left, string> {\n const query = new URLSearchParams(serializeInitDataQuery({\n ...data,\n auth_date: authDate,\n signature: data.signature || '',\n }));\n\n // Convert search params to pairs and sort the final array.\n const pairs = [...query.entries()]\n .map(([name, value]) => `${name}=${value}`)\n .sort();\n\n // Compute sign, append it to the params and return.\n const queryWithHash = (signature: string): string => {\n query.append('hash', signature);\n return query.toString();\n };\n\n const eitherHash = signData(pairs.join('\\n'), key, options);\n return typeof eitherHash === 'function'\n ? pipe(eitherHash, TE.chain(hash => TE.right(queryWithHash(hash))))\n : pipe(eitherHash, E.chain(hash => E.right(queryWithHash(hash))));\n}\n","import {\n BetterPromise,\n type BetterPromiseOptions,\n type BetterPromiseRejectReason,\n} from 'better-promises';\nimport * as E from 'fp-ts/Either';\nimport * as TE from 'fp-ts/TaskEither';\nimport { pipe } from 'fp-ts/function';\n\nimport {\n AuthDateInvalidError,\n ExpiredError,\n SignatureInvalidError,\n SignatureMissingError,\n} from './errors.js';\nimport { Text } from './types.js';\n\ntype OmittedPromiseOptions = Omit<BetterPromiseOptions, 'abortOnResolve' | 'abortOnReject'>;\n\nexport type ValidateValue = string | URLSearchParams;\nexport type Validate3rdValue = string | URLSearchParams;\n\nexport type ValidateError =\n | SignatureMissingError\n | SignatureInvalidError\n | AuthDateInvalidError\n | ExpiredError;\nexport type ValidateAsyncError = ValidateError | BetterPromiseRejectReason;\nexport type Validate3rdError =\n | SignatureMissingError\n | SignatureInvalidError\n | AuthDateInvalidError\n | ExpiredError\n | BetterPromiseRejectReason;\n\ninterface ValidateSignDataFpArg<Async extends boolean, Left> {\n (data: Text, key: Text, options?: ValidateOptions): Async extends true\n ? TE.TaskEither<Left, string>\n : E.Either<Left, string>;\n}\n\ninterface SharedValidateOptions {\n /**\n * Time in seconds which states, how long from creation time init data is considered valid.\n *\n * In other words, in case when authDate + expiresIn is before current time, init data is\n * recognized as expired.\n *\n * In case this value is equal to 0, the function does not check init data expiration.\n * @default 86400 (1 day)\n */\n expiresIn?: number;\n}\n\nexport interface ValidateOptions extends SharedValidateOptions {\n /**\n * True, if token is already hashed.\n * @default false\n */\n tokenHashed?: boolean;\n}\n\nexport interface ValidateAsyncOptions extends ValidateOptions, OmittedPromiseOptions {\n}\n\nexport interface Validate3rdOptions extends SharedValidateOptions, OmittedPromiseOptions {\n /**\n * When true, uses the test environment public key to validate init data.\n * @default false\n */\n test?: boolean;\n}\n\n/**\n * Validates passed init data using a publicly known Ee25519 key.\n * @param value - value to check.\n * @param botId - bot identifier\n * @param options - additional validation options.\n */\nexport function validate3rdFp(\n value: Validate3rdValue,\n botId: number,\n options: Validate3rdOptions = {},\n): TE.TaskEither<Validate3rdError, void> {\n // Init data required params.\n let authDate: Date | undefined;\n let authDateString: string | undefined;\n let signature: string | undefined;\n\n // All search params pairs presented as `k=v`.\n const pairs: string[] = [];\n\n // Iterate over all key-value pairs of parsed parameters and find required\n // parameters.\n (typeof value === 'string' ? new URLSearchParams(value) : value).forEach((value, key) => {\n if (key === 'hash') {\n return;\n }\n if (key === 'signature') {\n signature = value;\n return;\n }\n if (key === 'auth_date') {\n authDateString = value;\n const authDateNum = parseInt(value, 10);\n if (!Number.isNaN(authDateNum)) {\n authDate = new Date(authDateNum * 1000);\n }\n }\n\n pairs.push(`${key}=${value}`);\n });\n\n // Signature and auth date always required.\n if (!signature) {\n return TE.left(new SignatureMissingError(true));\n }\n\n if (!authDate) {\n return TE.left(new AuthDateInvalidError(authDateString));\n }\n\n // In case, expiration time passed, we do additional parameters check.\n const { expiresIn = 86400 } = options;\n if (expiresIn > 0) {\n // Check if init data expired.\n const expiresAtTs = authDate.getTime() + (expiresIn * 1000);\n const nowTs = Date.now();\n if (expiresAtTs < nowTs) {\n return TE.left(new ExpiredError(authDate, new Date(expiresAtTs), new Date(nowTs)));\n }\n }\n\n return pipe(\n TE.tryCatch(\n () => {\n return BetterPromise.fn(async () => {\n return crypto.subtle.verify(\n 'Ed25519',\n await crypto.subtle.importKey(\n 'raw',\n Buffer.from(\n options.test\n ? '40055058a4ee38156a06562e52eece92a771bcd8346a8c4615cb7376eddf72ec'\n : 'e7bf03a2fa4602af4580703d88dda5bb59f32ed8b02a56c187fe7d34caed242d',\n 'hex',\n ),\n 'Ed25519',\n false,\n ['verify'],\n ),\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n Buffer.from(signature as string, 'base64'),\n Buffer.from(`${botId}:WebAppData\\n${pairs.sort().join('\\n')}`),\n );\n }, options);\n },\n (e: unknown) => e,\n ),\n TE.chainW(isVerified => {\n return isVerified ? TE.right(undefined) : TE.left(new SignatureInvalidError());\n }),\n );\n}\n\n/**\n * @see validate3rdFp\n */\nexport function validate3rd(\n value: Validate3rdValue,\n botId: number,\n options?: Validate3rdOptions,\n): BetterPromise<void> {\n return BetterPromise.fn(async () => {\n await pipe(\n validate3rdFp(value, botId, options),\n TE.mapLeft(error => {\n throw error;\n }),\n )();\n });\n}\n\n/**\n * @param value - value to check.\n * @param botId - bot identifier\n * @param options - additional validation options.\n * @returns True is specified init data is signed by Telegram.\n */\nexport function isValid3rdFp(\n value: Validate3rdValue,\n botId: number,\n options?: Validate3rdOptions,\n): TE.TaskEither<void, boolean> {\n return pipe(validate3rdFp(value, botId, options), TE.match(\n () => E.right(false),\n () => E.right(true),\n ));\n}\n\n/**\n * @see isValid3rdFp\n */\nexport function isValid3rd(\n value: Validate3rdValue,\n botId: number,\n options?: Validate3rdOptions,\n): BetterPromise<boolean> {\n return BetterPromise.fn(() => pipe(\n isValid3rdFp(value, botId, options),\n TE.match(() => false, v => v),\n )());\n}\n\nexport function validateFp<Left>(\n async: false,\n value: ValidateValue,\n token: Text,\n signData: ValidateSignDataFpArg<false, Left>,\n options?: ValidateOptions,\n): E.Either<Left | ValidateError, void>;\n\nexport function validateFp<Left>(\n async: true,\n value: ValidateValue,\n token: Text,\n signData: ValidateSignDataFpArg<true, Left>,\n options?: ValidateAsyncOptions,\n): TE.TaskEither<Left | ValidateAsyncError, void>;\n\nexport function validateFp<Left>(\n async: boolean,\n value: ValidateValue,\n token: Text,\n signData: ValidateSignDataFpArg<boolean, Left>,\n options: ValidateOptions | ValidateAsyncOptions = {},\n):\n | E.Either<Left | ValidateError, void>\n | TE.TaskEither<Left | ValidateAsyncError, void> {\n // Init data required params.\n let authDate: Date | undefined;\n let authDateString: string | undefined;\n let hash: string | undefined;\n\n // All search params pairs presented as `k=v`.\n const pairs: string[] = [];\n\n // Iterate over all key-value pairs of parsed parameters and find required\n // parameters.\n (typeof value === 'string' ? new URLSearchParams(value) : value).forEach((value, key) => {\n if (key === 'hash') {\n hash = value;\n return;\n }\n\n if (key === 'auth_date') {\n authDateString = value;\n const authDateNum = parseInt(value, 10);\n if (!Number.isNaN(authDateNum)) {\n authDate = new Date(authDateNum * 1000);\n }\n }\n\n pairs.push(`${key}=${value}`);\n });\n\n // Hash and auth date always required.\n if (!hash) {\n return (async ? TE.left : E.left)(new SignatureMissingError(false));\n }\n\n if (!authDate) {\n return (async ? TE.left : E.left)(new AuthDateInvalidError(authDateString));\n }\n\n // In case, expiration time passed, we do additional parameters check.\n const { expiresIn = 86400 } = options;\n if (expiresIn > 0) {\n // Check if init data expired.\n const expiresAtTs = authDate.getTime() + (expiresIn * 1000);\n const nowTs = Date.now();\n if (expiresAtTs < nowTs) {\n return (async ? TE.left : E.left)(\n new ExpiredError(authDate, new Date(expiresAtTs), new Date(nowTs)),\n );\n }\n }\n\n // According to docs, we sort all the pairs in alphabetical order.\n pairs.sort();\n\n const eitherSignature = signData(pairs.join('\\n'), token, options);\n const onLeft = (error: Left) => E.left(error);\n const onRight = (signature: string) => (\n signature === hash ? E.right(undefined) : E.left(new SignatureInvalidError())\n );\n\n return typeof eitherSignature === 'function'\n ? pipe(eitherSignature, TE.matchW(onLeft, onRight))\n : pipe(eitherSignature, E.matchW(onLeft, onRight));\n}\n","import {\n parseInitDataQuery,\n parseInitDataQueryFp,\n type ParseInitDataQueryError,\n} from '@tma.js/transformers';\n\n/**\n * Parses an incoming value as init data.\n */\nexport const parse = parseInitDataQuery;\n\n/**\n * Parses an incoming value as init data.\n */\nexport const parseFp = parseInitDataQueryFp;\n\nexport { ParseInitDataQueryError as ParseError };\n"],"names":["value","pipe"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"parsing-pEQ1lsuE.cjs","sources":["../../src/errors.ts","../../src/buf-converters.ts","../../src/hashToken.ts","../../src/signDataFp.ts","../../src/signFp.ts","../../src/validation.ts","../../src/parsing.ts"],"sourcesContent":["import { errorClass, errorClassWithData } from 'error-kid';\n\nexport class AuthDateInvalidError extends errorClassWithData<\n { value: string | undefined },\n [value?: string]\n>(\n 'AuthDateInvalidError',\n value => ({ value }),\n value => [`\"auth_date\" is invalid: ${value || 'value is missing'}`],\n) {\n}\n\nexport class SignatureInvalidError extends errorClass('SignatureInvalidError') {\n}\n\nexport class HexStringLengthInvalidError extends errorClass(\n 'HexStringLengthInvalidError',\n) {\n}\n\nexport class SignatureMissingError extends errorClass<[thirdParty: boolean]>(\n 'SignatureMissingError',\n thirdParty => [`\"${thirdParty ? 'signature' : 'hash'}\" parameter is missing`],\n) {\n}\n\nexport class ExpiredError extends errorClassWithData<\n { issuedAt: Date; expiresAt: Date },\n [issuedAt: Date, expiresAt: Date, now: Date]\n>(\n 'ExpiredError',\n (issuedAt, expiresAt) => ({ issuedAt, expiresAt }),\n (issuedAt, expiresAt, now) => [\n `Init data expired. Issued at ${issuedAt.toISOString()}, expires at ${expiresAt.toISOString()}, now is ${now.toISOString()}`,\n ],\n) {\n}\n","import * as E from 'fp-ts/Either';\n\nimport { HexStringLengthInvalidError } from './errors.js';\n\n/**\n * Converts a hex string to ArrayBuffer.\n * @param hexString - value to convert.\n */\nexport function hexToArrayBuffer(hexString: string): E.Either<\n InstanceType<typeof HexStringLengthInvalidError>,\n ArrayBuffer\n> {\n if (hexString.length % 2 !== 0) {\n return E.left(new HexStringLengthInvalidError());\n }\n const buffer = new ArrayBuffer(hexString.length / 2);\n const uint8Array = new Uint8Array(buffer);\n for (let i = 0; i < hexString.length; i += 2) {\n uint8Array[i / 2] = parseInt(hexString.substring(i, i + 2), 16);\n }\n return E.right(buffer);\n}\n\n/**\n * Converts array buffer to hex.\n * @param arrBuf - buffer to convert\n */\nexport function arrayBufferToHex(arrBuf: ArrayBuffer): string {\n return new Uint8Array(arrBuf).reduce((acc, byte) => {\n // Convert byte to hex and pad with zero if needed (e.g., \"0a\" instead of \"a\")\n return acc + byte.toString(16).padStart(2, '0');\n }, '');\n}\n\nexport function bufferToArrayBuffer(buf: Buffer) {\n const ab = new ArrayBuffer(buf.length);\n buf.copy(new Uint8Array(ab));\n return ab;\n}\n","import type { CreateHmacFn, Text } from './types.js';\n\nexport function hashToken<H extends CreateHmacFn<any>>(token: Text, createHmac: H): ReturnType<H> {\n return createHmac(token, 'WebAppData') as ReturnType<H>;\n}\n","import * as E from 'fp-ts/Either';\nimport * as TE from 'fp-ts/TaskEither';\nimport { pipe } from 'fp-ts/lib/function.js';\n\nimport { arrayBufferToHex, hexToArrayBuffer } from './buf-converters.js';\nimport { hashToken } from './hashToken.js';\nimport type { CreateHmacFn, Text } from './types.js';\n\nexport interface SignDataOptions {\n /**\n * True, if token is already hashed and doesn't require hashing using HMAC-SHA-256.\n */\n tokenHashed?: boolean;\n}\n\nexport type SignDataError = ReturnType<typeof hexToArrayBuffer> extends E.Either<infer U, any>\n ? U\n : never;\n\nexport function signDataFp(\n async: false,\n data: Text,\n key: Text,\n createHmac: CreateHmacFn<false>,\n options?: SignDataOptions,\n): E.Either<SignDataError, string>;\n\nexport function signDataFp(\n async: true,\n data: Text,\n key: Text,\n createHmac: CreateHmacFn<true>,\n options?: SignDataOptions,\n): TE.TaskEither<SignDataError, string>;\n\nexport function signDataFp(\n async: boolean,\n data: Text,\n key: Text,\n createHmac: CreateHmacFn<boolean>,\n options: SignDataOptions = {},\n):\n | E.Either<SignDataError, string>\n | TE.TaskEither<SignDataError, string> {\n const keyHmac = options.tokenHashed\n ? typeof key === 'string'\n // If a hashed token was passed, we assume that it is a HEX string. Not to mess with\n // the createHmac function, we should convert this HEX string to ArrayBuffer. Otherwise,\n // incorrect behavior will be met.\n ? hexToArrayBuffer(key)\n : E.right(key)\n // Otherwise we are hashing the token, but we want it to be a monad.\n : pipe(\n E.right(hashToken(key, createHmac)),\n E.match(() => null as never, v => {\n return v instanceof Promise\n ? TE.tryCatch(() => v, err => err as SignDataError)\n : E.right(v);\n }),\n );\n\n if (async || typeof keyHmac === 'function') {\n return pipe(\n typeof keyHmac === 'function' ? keyHmac : TE.fromEither(keyHmac),\n TE.chain(v => TE.tryCatch(\n () => Promise.resolve(createHmac(data, v)).then(arrayBufferToHex),\n err => err as SignDataError,\n )),\n );\n }\n return pipe(\n keyHmac,\n // In this branch createHmac can't be asynchronous. If it is, keyHmac would be Promise and the\n // result would be returned in the previous \"if\" statement.\n E.chain(v => E.right(\n arrayBufferToHex((createHmac as CreateHmacFn<false>)(data, v)),\n )),\n );\n}\n","import { type InitDataLike, serializeInitDataQuery } from '@tma.js/transformers';\nimport * as E from 'fp-ts/Either';\nimport * as TE from 'fp-ts/TaskEither';\nimport { pipe } from 'fp-ts/lib/function.js';\n\nimport type { Text } from './types.js';\n\nexport type SignableData =\n & Omit<InitDataLike, 'auth_date' | 'hash' | 'signature'>\n & { signature?: string };\n\nexport interface SignOptions {\n /**\n * True, if token is already hashed and doesn't require hashing using HMAC-SHA-256.\n */\n tokenHashed?: boolean;\n}\n\ninterface SignDataFpArg<Async extends boolean, Left> {\n (data: Text, key: Text, options?: SignOptions): Async extends true\n ? TE.TaskEither<Left, string>\n : E.Either<Left, string>;\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 signData - function signing data.\n * @param options - additional options.\n * @returns Signed init data presented as query parameters.\n */\nexport function signFp<Left>(\n data: SignableData,\n key: Text,\n authDate: Date,\n signData: SignDataFpArg<false, Left>,\n options?: SignOptions,\n): E.Either<Left, string>;\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 signData - function signing data.\n * @param options - additional options.\n * @returns Signed init data presented as query parameters.\n */\nexport function signFp<Left>(\n data: SignableData,\n key: Text,\n authDate: Date,\n signData: SignDataFpArg<true, Left>,\n options?: SignOptions,\n): TE.TaskEither<Left, string>;\n\nexport function signFp<Left>(\n data: SignableData,\n key: Text,\n authDate: Date,\n signData: SignDataFpArg<boolean, Left>,\n options?: SignOptions,\n): E.Either<Left, string> | TE.TaskEither<Left, string> {\n const query = new URLSearchParams(serializeInitDataQuery({\n ...data,\n auth_date: authDate,\n signature: data.signature || '',\n }));\n\n // Convert search params to pairs and sort the final array.\n const pairs = [...query.entries()]\n .map(([name, value]) => `${name}=${value}`)\n .sort();\n\n // Compute sign, append it to the params and return.\n const queryWithHash = (signature: string): string => {\n query.append('hash', signature);\n return query.toString();\n };\n\n const eitherHash = signData(pairs.join('\\n'), key, options);\n return typeof eitherHash === 'function'\n ? pipe(eitherHash, TE.chain(hash => TE.right(queryWithHash(hash))))\n : pipe(eitherHash, E.chain(hash => E.right(queryWithHash(hash))));\n}\n","import {\n BetterPromise,\n type BetterPromiseOptions,\n type BetterPromiseRejectReason,\n} from 'better-promises';\nimport * as E from 'fp-ts/Either';\nimport * as TE from 'fp-ts/TaskEither';\nimport { pipe } from 'fp-ts/function';\n\nimport {\n AuthDateInvalidError,\n ExpiredError,\n SignatureInvalidError,\n SignatureMissingError,\n} from './errors.js';\nimport { Text } from './types.js';\n\ntype OmittedPromiseOptions = Omit<BetterPromiseOptions, 'abortOnResolve' | 'abortOnReject'>;\n\nexport type ValidateValue = string | URLSearchParams;\nexport type Validate3rdValue = string | URLSearchParams;\n\nexport type ValidateError =\n | SignatureMissingError\n | SignatureInvalidError\n | AuthDateInvalidError\n | ExpiredError;\nexport type ValidateAsyncError = ValidateError | BetterPromiseRejectReason;\nexport type Validate3rdError =\n | SignatureMissingError\n | SignatureInvalidError\n | AuthDateInvalidError\n | ExpiredError\n | BetterPromiseRejectReason;\n\ninterface ValidateSignDataFpArg<Async extends boolean, Left> {\n (data: Text, key: Text, options?: ValidateOptions): Async extends true\n ? TE.TaskEither<Left, string>\n : E.Either<Left, string>;\n}\n\ninterface SharedValidateOptions {\n /**\n * Time in seconds which states, how long from creation time init data is considered valid.\n *\n * In other words, in case when authDate + expiresIn is before current time, init data is\n * recognized as expired.\n *\n * In case this value is equal to 0, the function does not check init data expiration.\n * @default 86400 (1 day)\n */\n expiresIn?: number;\n}\n\nexport interface ValidateOptions extends SharedValidateOptions {\n /**\n * True, if token is already hashed.\n * @default false\n */\n tokenHashed?: boolean;\n}\n\nexport interface ValidateAsyncOptions extends ValidateOptions, OmittedPromiseOptions {\n}\n\nexport interface Validate3rdOptions extends SharedValidateOptions, OmittedPromiseOptions {\n /**\n * When true, uses the test environment public key to validate init data.\n * @default false\n */\n test?: boolean;\n}\n\n/**\n * Validates passed init data using a publicly known Ee25519 key.\n * @param value - value to check.\n * @param botId - bot identifier\n * @param options - additional validation options.\n */\nexport function validate3rdFp(\n value: Validate3rdValue,\n botId: number,\n options: Validate3rdOptions = {},\n): TE.TaskEither<Validate3rdError, void> {\n // Init data required params.\n let authDate: Date | undefined;\n let authDateString: string | undefined;\n let signature: string | undefined;\n\n // All search params pairs presented as `k=v`.\n const pairs: string[] = [];\n\n // Iterate over all key-value pairs of parsed parameters and find required\n // parameters.\n (typeof value === 'string' ? new URLSearchParams(value) : value).forEach((value, key) => {\n if (key === 'hash') {\n return;\n }\n if (key === 'signature') {\n signature = value;\n return;\n }\n if (key === 'auth_date') {\n authDateString = value;\n const authDateNum = parseInt(value, 10);\n if (!Number.isNaN(authDateNum)) {\n authDate = new Date(authDateNum * 1000);\n }\n }\n\n pairs.push(`${key}=${value}`);\n });\n\n // Signature and auth date always required.\n if (!signature) {\n return TE.left(new SignatureMissingError(true));\n }\n\n if (!authDate) {\n return TE.left(new AuthDateInvalidError(authDateString));\n }\n\n // In case, expiration time passed, we do additional parameters check.\n const { expiresIn = 86400 } = options;\n if (expiresIn > 0) {\n // Check if init data expired.\n const expiresAtTs = authDate.getTime() + (expiresIn * 1000);\n const nowTs = Date.now();\n if (expiresAtTs < nowTs) {\n return TE.left(new ExpiredError(authDate, new Date(expiresAtTs), new Date(nowTs)));\n }\n }\n\n return pipe(\n TE.tryCatch(\n () => {\n return BetterPromise.fn(async () => {\n return crypto.subtle.verify(\n 'Ed25519',\n await crypto.subtle.importKey(\n 'raw',\n Buffer.from(\n options.test\n ? '40055058a4ee38156a06562e52eece92a771bcd8346a8c4615cb7376eddf72ec'\n : 'e7bf03a2fa4602af4580703d88dda5bb59f32ed8b02a56c187fe7d34caed242d',\n 'hex',\n ),\n 'Ed25519',\n false,\n ['verify'],\n ),\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n Buffer.from(signature as string, 'base64'),\n Buffer.from(`${botId}:WebAppData\\n${pairs.sort().join('\\n')}`),\n );\n }, options);\n },\n (e: unknown) => e,\n ),\n TE.chainW(isVerified => {\n return isVerified ? TE.right(undefined) : TE.left(new SignatureInvalidError());\n }),\n );\n}\n\n/**\n * @see validate3rdFp\n */\nexport function validate3rd(\n value: Validate3rdValue,\n botId: number,\n options?: Validate3rdOptions,\n): BetterPromise<void> {\n return BetterPromise.fn(async () => {\n await pipe(\n validate3rdFp(value, botId, options),\n TE.mapLeft(error => {\n throw error;\n }),\n )();\n });\n}\n\n/**\n * @param value - value to check.\n * @param botId - bot identifier\n * @param options - additional validation options.\n * @returns True is specified init data is signed by Telegram.\n */\nexport function isValid3rdFp(\n value: Validate3rdValue,\n botId: number,\n options?: Validate3rdOptions,\n): TE.TaskEither<void, boolean> {\n return pipe(validate3rdFp(value, botId, options), TE.match(\n () => E.right(false),\n () => E.right(true),\n ));\n}\n\n/**\n * @see isValid3rdFp\n */\nexport function isValid3rd(\n value: Validate3rdValue,\n botId: number,\n options?: Validate3rdOptions,\n): BetterPromise<boolean> {\n return BetterPromise.fn(() => pipe(\n isValid3rdFp(value, botId, options),\n TE.match(() => false, v => v),\n )());\n}\n\nexport function validateFp<Left>(\n async: false,\n value: ValidateValue,\n token: Text,\n signData: ValidateSignDataFpArg<false, Left>,\n options?: ValidateOptions,\n): E.Either<Left | ValidateError, void>;\n\nexport function validateFp<Left>(\n async: true,\n value: ValidateValue,\n token: Text,\n signData: ValidateSignDataFpArg<true, Left>,\n options?: ValidateAsyncOptions,\n): TE.TaskEither<Left | ValidateAsyncError, void>;\n\nexport function validateFp<Left>(\n async: boolean,\n value: ValidateValue,\n token: Text,\n signData: ValidateSignDataFpArg<boolean, Left>,\n options: ValidateOptions | ValidateAsyncOptions = {},\n):\n | E.Either<Left | ValidateError, void>\n | TE.TaskEither<Left | ValidateAsyncError, void> {\n // Init data required params.\n let authDate: Date | undefined;\n let authDateString: string | undefined;\n let hash: string | undefined;\n\n // All search params pairs presented as `k=v`.\n const pairs: string[] = [];\n\n // Iterate over all key-value pairs of parsed parameters and find required\n // parameters.\n (typeof value === 'string' ? new URLSearchParams(value) : value).forEach((value, key) => {\n if (key === 'hash') {\n hash = value;\n return;\n }\n\n if (key === 'auth_date') {\n authDateString = value;\n const authDateNum = parseInt(value, 10);\n if (!Number.isNaN(authDateNum)) {\n authDate = new Date(authDateNum * 1000);\n }\n }\n\n pairs.push(`${key}=${value}`);\n });\n\n // Hash and auth date always required.\n if (!hash) {\n return (async ? TE.left : E.left)(new SignatureMissingError(false));\n }\n\n if (!authDate) {\n return (async ? TE.left : E.left)(new AuthDateInvalidError(authDateString));\n }\n\n // In case, expiration time passed, we do additional parameters check.\n const { expiresIn = 86400 } = options;\n if (expiresIn > 0) {\n // Check if init data expired.\n const expiresAtTs = authDate.getTime() + (expiresIn * 1000);\n const nowTs = Date.now();\n if (expiresAtTs < nowTs) {\n return (async ? TE.left : E.left)(\n new ExpiredError(authDate, new Date(expiresAtTs), new Date(nowTs)),\n );\n }\n }\n\n // According to docs, we sort all the pairs in alphabetical order.\n pairs.sort();\n\n const eitherSignature = signData(pairs.join('\\n'), token, options);\n const onLeft = (error: Left) => E.left(error);\n const onRight = (signature: string) => (\n signature === hash ? E.right(undefined) : E.left(new SignatureInvalidError())\n );\n\n return typeof eitherSignature === 'function'\n ? pipe(eitherSignature, TE.matchW(onLeft, onRight))\n : pipe(eitherSignature, E.matchW(onLeft, onRight));\n}\n","import {\n parseInitDataQuery,\n parseInitDataQueryFp,\n type ParseInitDataQueryError,\n} from '@tma.js/transformers';\n\n/**\n * Parses an incoming value as init data.\n */\nexport const parse = parseInitDataQuery;\n\n/**\n * Parses an incoming value as init data.\n */\nexport const parseFp = parseInitDataQueryFp;\n\nexport { ParseInitDataQueryError as ParseError };\n"],"names":["errorClassWithData","errorClass","E","pipe","TE","serializeInitDataQuery","value","BetterPromise","parseInitDataQuery","parseInitDataQueryFp"],"mappings":"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"}