@prosopo/server 2.1.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prosopo/server",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
4
4
  "description": "NodeJS package for server side communication with the prosopo captcha client",
5
5
  "main": "./dist/index.js",
6
6
  "type": "module",
@@ -34,13 +34,13 @@
34
34
  "dependencies": {
35
35
  "@polkadot/keyring": "12.6.2",
36
36
  "@polkadot/util": "12.6.2",
37
- "@prosopo/api": "2.1.0",
38
- "@prosopo/common": "2.1.0",
39
- "@prosopo/contract": "2.1.0",
40
- "@prosopo/types": "2.1.0"
37
+ "@prosopo/api": "2.1.2",
38
+ "@prosopo/common": "2.1.2",
39
+ "@prosopo/contract": "2.1.2",
40
+ "@prosopo/types": "2.1.2"
41
41
  },
42
42
  "devDependencies": {
43
- "@prosopo/config": "2.1.0",
43
+ "@prosopo/config": "2.1.2",
44
44
  "@vitest/coverage-v8": "2.1.1",
45
45
  "concurrently": "9.0.1",
46
46
  "npm-run-all": "4.1.5",
@@ -1,25 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const types = require("@prosopo/types");
4
- const getServerConfig = () => types.ProsopoServerConfigSchema.parse({
5
- defaultEnvironment: process.env.PROSOPO_DEFAULT_ENVIRONMENT,
6
- // enviromental variables
7
- serverUrl: getServerUrl(),
8
- dappName: process.env.PROSOPO_DAPP_NAME || "client-example-server",
9
- account: {
10
- password: "",
11
- address: process.env.PROSOPO_SITE_KEY || "",
12
- secret: process.env.PROSOPO_SITE_PRIVATE_KEY || ""
13
- }
14
- });
15
- const getServerUrl = () => {
16
- if (process.env.PROSOPO_SERVER_URL) {
17
- if (process.env.PROSOPO_SERVER_URL.match(/:\d+/)) {
18
- return process.env.PROSOPO_SERVER_URL;
19
- }
20
- return `${process.env.PROSOPO_SERVER_URL}:${process.env.PROSOPO_SERVER_PORT || 9228}`;
21
- }
22
- return "http://localhost:9228";
23
- };
24
- exports.getServerConfig = getServerConfig;
25
- exports.getServerUrl = getServerUrl;
@@ -1,13 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const server = require("./server.cjs");
4
- const config = require("./config.cjs");
5
- const contract = require("@prosopo/contract");
6
- const PublicProsopoServer = async (config2) => {
7
- const pair = await contract.getPairAsync(void 0, config2.account.address);
8
- return new server.ProsopoServer(config2, pair);
9
- };
10
- exports.ProsopoServer = server.ProsopoServer;
11
- exports.getServerConfig = config.getServerConfig;
12
- exports.getServerUrl = config.getServerUrl;
13
- exports.PublicProsopoServer = PublicProsopoServer;
@@ -1,97 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const keyring = require("@polkadot/keyring");
4
- const util = require("@polkadot/util");
5
- const api = require("@prosopo/api");
6
- const common = require("@prosopo/common");
7
- const types = require("@prosopo/types");
8
- class ProsopoServer {
9
- constructor(config, pair) {
10
- this.config = config;
11
- this.pair = pair;
12
- this.defaultEnvironment = this.config.defaultEnvironment;
13
- this.dappAccount = this.config.account.address;
14
- this.logger = common.getLogger(
15
- this.config.logLevel,
16
- "@prosopo/server"
17
- );
18
- this.keyring = new keyring.Keyring({
19
- type: "sr25519"
20
- });
21
- }
22
- getProviderApi(providerUrl) {
23
- return new api.ProviderApi(providerUrl, this.dappAccount || "");
24
- }
25
- /**
26
- * Verify the user with the provider URL passed in. If a challenge is provided, we use the challenge to verify the
27
- * user. If not, we use the user, dapp, and optionally the commitmentID, to verify the user.
28
- * @param token
29
- * @param timeouts
30
- * @param providerUrl
31
- * @param timestamp
32
- * @param challenge
33
- */
34
- async verifyProvider(token, timeouts, providerUrl, timestamp, challenge) {
35
- this.logger.info("Verifying with provider.");
36
- const dappUserSignature = this.pair?.sign(timestamp.toString());
37
- if (!dappUserSignature) {
38
- throw new common.ProsopoContractError("CAPTCHA.INVALID_TIMESTAMP", {
39
- context: { error: "Timestamp not found" }
40
- });
41
- }
42
- const signatureHex = util.u8aToHex(dappUserSignature);
43
- const providerApi = this.getProviderApi(providerUrl);
44
- if (challenge) {
45
- const powTimeout = this.config.timeouts.pow.cachedTimeout;
46
- const recent2 = timestamp ? Date.now() - timestamp < powTimeout : false;
47
- if (!recent2) {
48
- this.logger.error("PoW captcha is not recent");
49
- return false;
50
- }
51
- const result2 = await providerApi.submitPowCaptchaVerify(
52
- token,
53
- signatureHex,
54
- timeouts.pow.cachedTimeout
55
- );
56
- return result2.verified;
57
- }
58
- const imageTimeout = this.config.timeouts.image.cachedTimeout;
59
- const recent = timestamp ? Date.now() - timestamp < imageTimeout : false;
60
- if (!recent) {
61
- this.logger.error("Image captcha is not recent");
62
- return false;
63
- }
64
- const result = await providerApi.verifyDappUser(
65
- token,
66
- signatureHex,
67
- timeouts.image.cachedTimeout
68
- );
69
- return result.verified;
70
- }
71
- /**
72
- *
73
- * @returns
74
- * @param token
75
- */
76
- async isVerified(token) {
77
- if (!util.isHex(token)) {
78
- this.logger.error("Invalid token - not hex", token);
79
- return false;
80
- }
81
- const payload = types.decodeProcaptchaOutput(token);
82
- const { providerUrl, challenge, timestamp } = types.ProcaptchaOutputSchema.parse(payload);
83
- if (providerUrl) {
84
- return await this.verifyProvider(
85
- token,
86
- this.config.timeouts,
87
- providerUrl,
88
- Number(timestamp),
89
- challenge
90
- );
91
- }
92
- throw new common.ProsopoApiError("API.BAD_REQUEST", {
93
- context: { message: "No provider URL" }
94
- });
95
- }
96
- }
97
- exports.ProsopoServer = ProsopoServer;
package/dist/config.d.ts DELETED
@@ -1,39 +0,0 @@
1
- export declare const getServerConfig: () => {
2
- timeouts: {
3
- image: {
4
- verifiedTimeout: number;
5
- challengeTimeout: number;
6
- solutionTimeout: number;
7
- cachedTimeout: number;
8
- };
9
- contract: {
10
- maxVerifiedTime: number;
11
- };
12
- pow: {
13
- verifiedTimeout: number;
14
- solutionTimeout: number;
15
- cachedTimeout: number;
16
- };
17
- };
18
- logLevel: "trace" | "debug" | "info" | "warn" | "error" | "fatal" | "log";
19
- defaultEnvironment: "development" | "staging" | "production";
20
- account: {
21
- secret?: string | undefined;
22
- address?: string | undefined;
23
- password?: string | undefined;
24
- };
25
- web2: boolean;
26
- solutionThreshold: number;
27
- dappName: string;
28
- database?: Partial<Record<"development" | "staging" | "production", {
29
- type: string;
30
- endpoint: string;
31
- dbname: string;
32
- authSource: string;
33
- }>> | undefined;
34
- devOnlyWatchEvents?: boolean | undefined;
35
- userAccountAddress?: string | undefined;
36
- serverUrl?: string | undefined;
37
- };
38
- export declare const getServerUrl: () => string;
39
- //# sourceMappingURL=config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;cAqByghB,CAAC;eAAqC,CAAC;gBAAsC,CAAC;;;;;;;;;;;;;;CAXhnhB,CAAC;AAEJ,eAAO,MAAM,YAAY,QAAO,MAQ/B,CAAC"}
package/dist/config.js DELETED
@@ -1,21 +0,0 @@
1
- import { ProsopoServerConfigSchema } from "@prosopo/types";
2
- export const getServerConfig = () => ProsopoServerConfigSchema.parse({
3
- defaultEnvironment: process.env.PROSOPO_DEFAULT_ENVIRONMENT,
4
- serverUrl: getServerUrl(),
5
- dappName: process.env.PROSOPO_DAPP_NAME || "client-example-server",
6
- account: {
7
- password: "",
8
- address: process.env.PROSOPO_SITE_KEY || "",
9
- secret: process.env.PROSOPO_SITE_PRIVATE_KEY || "",
10
- },
11
- });
12
- export const getServerUrl = () => {
13
- if (process.env.PROSOPO_SERVER_URL) {
14
- if (process.env.PROSOPO_SERVER_URL.match(/:\d+/)) {
15
- return process.env.PROSOPO_SERVER_URL;
16
- }
17
- return `${process.env.PROSOPO_SERVER_URL}:${process.env.PROSOPO_SERVER_PORT || 9228}`;
18
- }
19
- return "http://localhost:9228";
20
- };
21
- //# sourceMappingURL=config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAE3D,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE,CACnC,yBAAyB,CAAC,KAAK,CAAC;IAC/B,kBAAkB,EAAE,OAAO,CAAC,GAAG,CAAC,2BAA2B;IAC3D,SAAS,EAAE,YAAY,EAAE;IACzB,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,uBAAuB;IAClE,OAAO,EAAE;QACR,QAAQ,EAAE,EAAE;QACZ,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE;QAC3C,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,EAAE;KAClD;CACD,CAAC,CAAC;AAEJ,MAAM,CAAC,MAAM,YAAY,GAAG,GAAW,EAAE;IACxC,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;QACpC,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YAClD,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;QACvC,CAAC;QACD,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,IAAI,EAAE,CAAC;IACvF,CAAC;IACD,OAAO,uBAAuB,CAAC;AAChC,CAAC,CAAC"}
package/dist/index.d.ts DELETED
@@ -1,6 +0,0 @@
1
- import { ProsopoServer } from "./server.js";
2
- export { ProsopoServer } from "./server.js";
3
- export { getServerConfig, getServerUrl } from "./config.js";
4
- import type { ProsopoServerConfigOutput } from "@prosopo/types";
5
- export declare const PublicProsopoServer: (config: ProsopoServerConfigOutput) => Promise<ProsopoServer>;
6
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE5D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAChE,eAAO,MAAM,mBAAmB,WACvB,yBAAyB,2BAKjC,CAAC"}
package/dist/index.js DELETED
@@ -1,9 +0,0 @@
1
- import { ProsopoServer } from "./server.js";
2
- export { ProsopoServer } from "./server.js";
3
- export { getServerConfig, getServerUrl } from "./config.js";
4
- import { getPairAsync } from "@prosopo/contract";
5
- export const PublicProsopoServer = async (config) => {
6
- const pair = await getPairAsync(undefined, config.account.address);
7
- return new ProsopoServer(config, pair);
8
- };
9
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EACvC,MAAiC,EAChC,EAAE;IAEH,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACnE,OAAO,IAAI,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC,CAAC"}
package/dist/server.d.ts DELETED
@@ -1,18 +0,0 @@
1
- import { Keyring } from "@polkadot/keyring";
2
- import type { KeyringPair } from "@polkadot/keyring/types";
3
- import { ProviderApi } from "@prosopo/api";
4
- import { type Logger } from "@prosopo/common";
5
- import { type CaptchaTimeoutOutput, type ProcaptchaToken, type ProsopoServerConfigOutput } from "@prosopo/types";
6
- export declare class ProsopoServer {
7
- config: ProsopoServerConfigOutput;
8
- dappAccount: string | undefined;
9
- defaultEnvironment: string;
10
- logger: Logger;
11
- keyring: Keyring;
12
- pair: KeyringPair | undefined;
13
- constructor(config: ProsopoServerConfigOutput, pair?: KeyringPair);
14
- getProviderApi(providerUrl: string): ProviderApi;
15
- verifyProvider(token: string, timeouts: CaptchaTimeoutOutput, providerUrl: string, timestamp: number, challenge?: string): Promise<boolean>;
16
- isVerified(token: ProcaptchaToken): Promise<boolean>;
17
- }
18
- //# sourceMappingURL=server.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAEN,KAAK,MAAM,EAIX,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,KAAK,oBAAoB,EAEzB,KAAK,eAAe,EACpB,KAAK,yBAAyB,EAC9B,MAAM,gBAAgB,CAAC;AAGxB,qBAAa,aAAa;IACzB,MAAM,EAAE,yBAAyB,CAAC;IAClC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,WAAW,GAAG,SAAS,CAAC;gBAElB,MAAM,EAAE,yBAAyB,EAAE,IAAI,CAAC,EAAE,WAAW;IAcjE,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW;IAanC,cAAc,CAC1B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,oBAAoB,EAC9B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM;IA6CN,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;CAyBjE"}
package/dist/server.js DELETED
@@ -1,65 +0,0 @@
1
- import { Keyring } from "@polkadot/keyring";
2
- import { isHex, u8aToHex } from "@polkadot/util";
3
- import { ProviderApi } from "@prosopo/api";
4
- import { ProsopoApiError, ProsopoContractError, getLogger, } from "@prosopo/common";
5
- import { ProcaptchaOutputSchema, } from "@prosopo/types";
6
- import { decodeProcaptchaOutput } from "@prosopo/types";
7
- export class ProsopoServer {
8
- constructor(config, pair) {
9
- this.config = config;
10
- this.pair = pair;
11
- this.defaultEnvironment = this.config.defaultEnvironment;
12
- this.dappAccount = this.config.account.address;
13
- this.logger = getLogger(this.config.logLevel, "@prosopo/server");
14
- this.keyring = new Keyring({
15
- type: "sr25519",
16
- });
17
- }
18
- getProviderApi(providerUrl) {
19
- return new ProviderApi(providerUrl, this.dappAccount || "");
20
- }
21
- async verifyProvider(token, timeouts, providerUrl, timestamp, challenge) {
22
- this.logger.info("Verifying with provider.");
23
- const dappUserSignature = this.pair?.sign(timestamp.toString());
24
- if (!dappUserSignature) {
25
- throw new ProsopoContractError("CAPTCHA.INVALID_TIMESTAMP", {
26
- context: { error: "Timestamp not found" },
27
- });
28
- }
29
- const signatureHex = u8aToHex(dappUserSignature);
30
- const providerApi = this.getProviderApi(providerUrl);
31
- if (challenge) {
32
- const powTimeout = this.config.timeouts.pow.cachedTimeout;
33
- const recent = timestamp ? Date.now() - timestamp < powTimeout : false;
34
- if (!recent) {
35
- this.logger.error("PoW captcha is not recent");
36
- return false;
37
- }
38
- const result = await providerApi.submitPowCaptchaVerify(token, signatureHex, timeouts.pow.cachedTimeout);
39
- return result.verified;
40
- }
41
- const imageTimeout = this.config.timeouts.image.cachedTimeout;
42
- const recent = timestamp ? Date.now() - timestamp < imageTimeout : false;
43
- if (!recent) {
44
- this.logger.error("Image captcha is not recent");
45
- return false;
46
- }
47
- const result = await providerApi.verifyDappUser(token, signatureHex, timeouts.image.cachedTimeout);
48
- return result.verified;
49
- }
50
- async isVerified(token) {
51
- if (!isHex(token)) {
52
- this.logger.error("Invalid token - not hex", token);
53
- return false;
54
- }
55
- const payload = decodeProcaptchaOutput(token);
56
- const { providerUrl, challenge, timestamp } = ProcaptchaOutputSchema.parse(payload);
57
- if (providerUrl) {
58
- return await this.verifyProvider(token, this.config.timeouts, providerUrl, Number(timestamp), challenge);
59
- }
60
- throw new ProsopoApiError("API.BAD_REQUEST", {
61
- context: { message: "No provider URL" },
62
- });
63
- }
64
- }
65
- //# sourceMappingURL=server.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}