@prosopo/server 2.5.3 → 2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/dist/cjs/config.cjs +25 -0
- package/dist/cjs/index.cjs +13 -0
- package/dist/cjs/server.cjs +114 -0
- package/package.json +12 -10
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# @prosopo/server
|
|
2
|
+
|
|
3
|
+
## 2.6.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [52feffc]
|
|
8
|
+
- @prosopo/types@2.6.1
|
|
9
|
+
- @prosopo/api@2.6.1
|
|
10
|
+
- @prosopo/keyring@2.6.1
|
|
11
|
+
- @prosopo/load-balancer@2.6.1
|
|
12
|
+
|
|
13
|
+
## 2.6.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- a0bfc8a: bump all pkg versions since independent versioning applied
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Updated dependencies [a0bfc8a]
|
|
22
|
+
- @prosopo/api@2.6.0
|
|
23
|
+
- @prosopo/common@2.6.0
|
|
24
|
+
- @prosopo/keyring@2.6.0
|
|
25
|
+
- @prosopo/load-balancer@2.6.0
|
|
26
|
+
- @prosopo/types@2.6.0
|
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
// environmental 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;
|
|
@@ -0,0 +1,13 @@
|
|
|
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 keyring = require("@prosopo/keyring");
|
|
6
|
+
const PublicProsopoServer = async (config2) => {
|
|
7
|
+
const pair = await keyring.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;
|
|
@@ -0,0 +1,114 @@
|
|
|
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 loadBalancer = require("@prosopo/load-balancer");
|
|
8
|
+
const types = require("@prosopo/types");
|
|
9
|
+
const i18n = require("i18next");
|
|
10
|
+
class ProsopoServer {
|
|
11
|
+
constructor(config, pair) {
|
|
12
|
+
this.config = config;
|
|
13
|
+
this.pair = pair;
|
|
14
|
+
this.defaultEnvironment = this.config.defaultEnvironment;
|
|
15
|
+
this.dappAccount = this.config.account.address;
|
|
16
|
+
this.logger = common.getLogger(
|
|
17
|
+
this.config.logLevel,
|
|
18
|
+
"@prosopo/server"
|
|
19
|
+
);
|
|
20
|
+
this.keyring = new keyring.Keyring({
|
|
21
|
+
type: "sr25519"
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
getProviderApi(providerUrl) {
|
|
25
|
+
return new api.ProviderApi(providerUrl, this.dappAccount || "");
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Verify the user with the provider URL passed in. If a challenge is provided, we use the challenge to verify the
|
|
29
|
+
* user. If not, we use the user, dapp, and optionally the commitmentID, to verify the user.
|
|
30
|
+
* @param token
|
|
31
|
+
* @param timeouts
|
|
32
|
+
* @param providerUrl
|
|
33
|
+
* @param timestamp
|
|
34
|
+
* @param user
|
|
35
|
+
* @param challenge
|
|
36
|
+
*/
|
|
37
|
+
async verifyProvider(token, timeouts, providerUrl, timestamp, user, challenge) {
|
|
38
|
+
this.logger.info(`Verifying with provider: ${providerUrl}`);
|
|
39
|
+
const dappUserSignature = this.pair?.sign(timestamp.toString());
|
|
40
|
+
if (!dappUserSignature) {
|
|
41
|
+
throw new common.ProsopoContractError("CAPTCHA.INVALID_TIMESTAMP", {
|
|
42
|
+
context: { error: "Timestamp not found" }
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
const signatureHex = util.u8aToHex(dappUserSignature);
|
|
46
|
+
const providerApi = this.getProviderApi(providerUrl);
|
|
47
|
+
if (challenge) {
|
|
48
|
+
const powTimeout = this.config.timeouts.pow.cachedTimeout;
|
|
49
|
+
const recent2 = timestamp ? Date.now() - timestamp < powTimeout : false;
|
|
50
|
+
if (!recent2) {
|
|
51
|
+
this.logger.error("PoW captcha is not recent");
|
|
52
|
+
return {
|
|
53
|
+
verified: false,
|
|
54
|
+
status: i18n.t("API.USER_NOT_VERIFIED_TIME_EXPIRED")
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return await providerApi.submitPowCaptchaVerify(
|
|
58
|
+
token,
|
|
59
|
+
signatureHex,
|
|
60
|
+
timeouts.pow.cachedTimeout,
|
|
61
|
+
user
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
const imageTimeout = this.config.timeouts.image.cachedTimeout;
|
|
65
|
+
const recent = timestamp ? Date.now() - timestamp < imageTimeout : false;
|
|
66
|
+
if (!recent) {
|
|
67
|
+
this.logger.error("Image captcha is not recent");
|
|
68
|
+
return {
|
|
69
|
+
verified: false,
|
|
70
|
+
status: i18n.t("API.USER_NOT_VERIFIED_TIME_EXPIRED")
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return await providerApi.verifyDappUser(
|
|
74
|
+
token,
|
|
75
|
+
signatureHex,
|
|
76
|
+
user,
|
|
77
|
+
timeouts.image.cachedTimeout
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
*
|
|
82
|
+
* @returns
|
|
83
|
+
* @param token
|
|
84
|
+
*/
|
|
85
|
+
async isVerified(token) {
|
|
86
|
+
try {
|
|
87
|
+
const payload = types.decodeProcaptchaOutput(token);
|
|
88
|
+
const { providerUrl, challenge, timestamp, user } = types.ProcaptchaOutputSchema.parse(payload);
|
|
89
|
+
const providers = await loadBalancer.loadBalancer(this.config.defaultEnvironment);
|
|
90
|
+
const provider = providers.find((p) => p.url === providerUrl);
|
|
91
|
+
if (!provider) {
|
|
92
|
+
this.logger.error("Provider not found");
|
|
93
|
+
return {
|
|
94
|
+
verified: false,
|
|
95
|
+
status: i18n.t("API.USER_NOT_VERIFIED")
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return await this.verifyProvider(
|
|
99
|
+
token,
|
|
100
|
+
this.config.timeouts,
|
|
101
|
+
provider.url,
|
|
102
|
+
Number(timestamp),
|
|
103
|
+
user,
|
|
104
|
+
challenge
|
|
105
|
+
);
|
|
106
|
+
} catch (err) {
|
|
107
|
+
this.logger.error({ err, token });
|
|
108
|
+
throw new common.ProsopoApiError("API.BAD_REQUEST", {
|
|
109
|
+
context: { code: 500, token }
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.ProsopoServer = ProsopoServer;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prosopo/server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.1",
|
|
4
4
|
"description": "NodeJS package for server side communication with the prosopo captcha client",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
},
|
|
23
23
|
"repository": {
|
|
24
24
|
"type": "git",
|
|
25
|
-
"url": "git+https://github.com/prosopo/captcha.git"
|
|
25
|
+
"url": "git+https://github.com/prosopo/captcha.git",
|
|
26
|
+
"directory": "packages/server"
|
|
26
27
|
},
|
|
27
28
|
"author": "PROSOPO LIMITED",
|
|
28
29
|
"license": "Apache-2.0",
|
|
@@ -34,22 +35,23 @@
|
|
|
34
35
|
"dependencies": {
|
|
35
36
|
"@polkadot/keyring": "12.6.2",
|
|
36
37
|
"@polkadot/util": "12.6.2",
|
|
37
|
-
"@prosopo/api": "2.
|
|
38
|
-
"@prosopo/common": "2.
|
|
39
|
-
"@prosopo/keyring": "2.
|
|
40
|
-
"@prosopo/
|
|
38
|
+
"@prosopo/api": "2.6.1",
|
|
39
|
+
"@prosopo/common": "2.6.0",
|
|
40
|
+
"@prosopo/keyring": "2.6.1",
|
|
41
|
+
"@prosopo/load-balancer": "2.6.1",
|
|
42
|
+
"@prosopo/types": "2.6.1",
|
|
41
43
|
"express": "4.21.2"
|
|
42
44
|
},
|
|
43
45
|
"devDependencies": {
|
|
44
|
-
"@prosopo/config": "2.
|
|
45
|
-
"@vitest/coverage-v8": "
|
|
46
|
+
"@prosopo/config": "2.6.0",
|
|
47
|
+
"@vitest/coverage-v8": "3.0.9",
|
|
46
48
|
"concurrently": "9.0.1",
|
|
47
49
|
"del-cli": "6.0.0",
|
|
48
50
|
"npm-run-all": "2.1.0",
|
|
49
51
|
"tslib": "2.7.0",
|
|
50
52
|
"tsx": "4.19.1",
|
|
51
53
|
"typescript": "5.6.2",
|
|
52
|
-
"vite": "
|
|
53
|
-
"vitest": "
|
|
54
|
+
"vite": "6.2.3",
|
|
55
|
+
"vitest": "3.0.9"
|
|
54
56
|
}
|
|
55
57
|
}
|