Skip to content

Commit

Permalink
Merge branch 'release/2.1.1' of github.com:prosopo/captcha into relea…
Browse files Browse the repository at this point in the history
…se/2.1.1
  • Loading branch information
forgetso committed Sep 24, 2024
2 parents cbeb798 + 9b698b7 commit 346cdf5
Show file tree
Hide file tree
Showing 50 changed files with 662 additions and 236 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/cypress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,15 @@ jobs:

- name: Run the cypress tests on client-example
run: |
npx concurrently "npm run start:server" "npm run start:provider" "npm run start:demo" "sleep 10s && npm -w @prosopo/cypress-shared run cypress:run:client-example" --success "first" --kill-others
npx concurrently "npm run start:server" "npm run start:provider:admin" "npm run start:demo" "sleep 10s && npm -w @prosopo/cypress-shared run cypress:run:client-example" --success "first" --kill-others
- name: Run the cypress tests on client-bundle-example
run: |
npx concurrently "npm run start:server" "npm run start:provider" "npm run start:bundle" "sleep 10s && npm -w @prosopo/cypress-shared run cypress:run:client-bundle-example" --success "first" --kill-others
npx concurrently "npm run start:server" "npm run start:provider:admin" "npm run start:bundle" "sleep 10s && npm -w @prosopo/cypress-shared run cypress:run:client-bundle-example" --success "first" --kill-others
- name: Run the cypress tests on client-bundle-example explicit rendering
run: |
npx concurrently "npm run start:server" "npm run start:provider" "npm run start:bundle" "sleep 10s && npm -w @prosopo/cypress-shared run cypress:run:client-bundle-example:explicit" --success "first" --kill-others
npx concurrently "npm run start:server" "npm run start:provider:admin" "npm run start:bundle" "sleep 10s && npm -w @prosopo/cypress-shared run cypress:run:client-bundle-example:explicit" --success "first" --kill-others
# after the test run completes store videos and any screenshots
- uses: actions/upload-artifact@v4
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
echo "******************************"
echo "inputs:" "$INPUTS_CONTEXT"
echo "******************************"
- run: mkdir -p ~/.npm
- run: mkdir -p ~/.cache/Cypress

Expand All @@ -71,7 +71,7 @@ jobs:
key: some-unused-cache-key
restore-keys: |
npm-${{ runner.os }}-${{ runner.arch }}-
- uses: actions/checkout@v3

- name: Detect env
Expand Down Expand Up @@ -139,15 +139,15 @@ jobs:

# this will error if there's already a release for this version. This is by design, if you need to fix a release (e.g. because a deploy failed) then bump the version and try again
- name: Github release
id: github_release
id: github_release_create
if: ${{ steps.env.outputs.production }} || ${{ steps.env.outputs.staging }}
continue-on-error: true # we want to continue even if the release already exists
run: |
gh release create --generate-notes "${{ steps.env.outputs.gh_release_tag }}"
# this will error if there's already a release for this version. This is by design, if you need to fix a release (e.g. because a deploy failed) then bump the version and try again
- name: Mark Github staging release as prerelease
id: github_release
id: github_release_edit
if: ${{ steps.env.outputs.staging }}
continue-on-error: true # we want to continue even if the release already exists
run: |
Expand Down
3 changes: 3 additions & 0 deletions demos/client-example/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ export default defineConfig(async ({ command, mode }) => {
"process.env.PROSOPO_LOG_LEVEL": JSON.stringify(
process.env.PROSOPO_LOG_LEVEL || "Info",
),
"process.env.PROSOPO_DOCS_URL": JSON.stringify(
process.env.PROSOPO_DOCS_URL,
),
},
build: {
outDir: path.resolve("./dist"),
Expand Down
9 changes: 7 additions & 2 deletions demos/cypress-shared/cypress.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { defineConfig } from "cypress";
import vitePreprocessor from "cypress-vite";
// Copyright 2021-2024 Prosopo (UK) Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -13,12 +11,19 @@ import vitePreprocessor from "cypress-vite";
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { loadEnv } from "@prosopo/dotenv";
import { defineConfig } from "cypress";
import vitePreprocessor from "cypress-vite";
import { nodePolyfills } from "vite-plugin-node-polyfills";

loadEnv();

export default defineConfig({
video: true,
headers: { "Accept-Encoding": "gzip, deflate" },
env: {
...process.env,
default_page: "/",
},
e2e: {
Expand Down
22 changes: 21 additions & 1 deletion demos/cypress-shared/cypress/e2e/captcha.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,33 @@
// limitations under the License.
/// <reference types="cypress" />
import "@cypress/xpath";
import { u8aToHex } from "@polkadot/util";
import { ProsopoDatasetError } from "@prosopo/common";
import { getPairAsync } from "@prosopo/contract";
import { datasetWithSolutionHashes } from "@prosopo/datasets";
import type { Captcha } from "@prosopo/types";
import { AdminApiPaths, type Captcha } from "@prosopo/types";
import { at } from "@prosopo/util";
import { checkboxClass } from "../support/commands.js";

describe("Captchas", () => {
before(async () => {
const timestamp = new Date().getTime();
const pair = await getPairAsync(Cypress.env("PROSOPO_PROVIDER_MNEMONIC"));
const signature = u8aToHex(pair.sign(timestamp.toString()));
const adminSiteKeyURL = `http://localhost:9229${AdminApiPaths.SiteKeyRegister}`;
await fetch(adminSiteKeyURL, {
method: "POST",
headers: {
"Content-Type": "application/json",
signature: signature,
timestamp: timestamp.toString(),
},
body: JSON.stringify({
siteKey: Cypress.env("PROSOPO_SITE_KEY"),
}),
});
});

beforeEach(() => {
const solutions = datasetWithSolutionHashes.captchas.map((captcha) => ({
captchaContentId: captcha.captchaContentId,
Expand Down
22 changes: 21 additions & 1 deletion demos/cypress-shared/cypress/e2e/correct.captcha.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,32 @@
// limitations under the License.
/// <reference types="cypress" />
import "@cypress/xpath";
import { u8aToHex } from "@polkadot/util";
import { ProsopoDatasetError } from "@prosopo/common";
import { getPairAsync } from "@prosopo/contract";
import { datasetWithSolutionHashes } from "@prosopo/datasets";
import type { Captcha } from "@prosopo/types";
import { AdminApiPaths, type Captcha } from "@prosopo/types";
import { checkboxClass } from "../support/commands.js";

describe("Captchas", () => {
before(async () => {
const timestamp = new Date().getTime();
const pair = await getPairAsync(Cypress.env("PROSOPO_PROVIDER_MNEMONIC"));
const signature = u8aToHex(pair.sign(timestamp.toString()));
const adminSiteKeyURL = `http://localhost:9229${AdminApiPaths.SiteKeyRegister}`;
await fetch(adminSiteKeyURL, {
method: "POST",
headers: {
"Content-Type": "application/json",
signature: signature,
timestamp: timestamp.toString(),
},
body: JSON.stringify({
siteKey: Cypress.env("PROSOPO_SITE_KEY"),
}),
});
});

beforeEach(() => {
const solutions = datasetWithSolutionHashes.captchas.map((captcha) => ({
captchaContentId: captcha.captchaContentId,
Expand Down
22 changes: 21 additions & 1 deletion demos/cypress-shared/cypress/e2e/correct.captcha.signup.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,32 @@
// limitations under the License.
/// <reference types="cypress" />
import "@cypress/xpath";
import { u8aToHex } from "@polkadot/util";
import { ProsopoDatasetError } from "@prosopo/common";
import { getPairAsync } from "@prosopo/contract";
import { datasetWithSolutionHashes } from "@prosopo/datasets";
import type { Captcha } from "@prosopo/types";
import { AdminApiPaths, type Captcha } from "@prosopo/types";
import { checkboxClass } from "../support/commands.js";

describe("Captchas", () => {
before(async () => {
const timestamp = new Date().getTime();
const pair = await getPairAsync(Cypress.env("PROSOPO_PROVIDER_MNEMONIC"));
const signature = u8aToHex(pair.sign(timestamp.toString()));
const adminSiteKeyURL = `http://localhost:9229${AdminApiPaths.SiteKeyRegister}`;
await fetch(adminSiteKeyURL, {
method: "POST",
headers: {
"Content-Type": "application/json",
signature: signature,
timestamp: timestamp.toString(),
},
body: JSON.stringify({
siteKey: Cypress.env("PROSOPO_SITE_KEY"),
}),
});
});

beforeEach(() => {
const solutions = datasetWithSolutionHashes.captchas.map((captcha) => ({
captchaContentId: captcha.captchaContentId,
Expand Down
3 changes: 3 additions & 0 deletions dev/config/src/vite/vite.frontend.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ export default async function (
"process.env.PROSOPO_PACKAGE_VERSION": JSON.stringify(
process.env.PROSOPO_PACKAGE_VERSION,
),
"process.env.PROSOPO_DOCS_URL": JSON.stringify(
process.env.PROSOPO_DOCS_URL,
),
// only needed if bundling with a site key
"process.env.PROSOPO_SITE_KEY": JSON.stringify(
process.env.PROSOPO_SITE_KEY,
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"setup": "npm -w @prosopo/scripts run setup",
"setup:all": "npm run setup",
"start:provider": "npm -w @prosopo/cli run start",
"start:provider:admin": "npm -w @prosopo/cli run start:admin",
"start:server": "npm -w @prosopo/client-example-server run start",
"start:demo": "npm -w @prosopo/client-example run start",
"start:bundle": "npm -w @prosopo/client-bundle-example run start",
Expand Down
6 changes: 5 additions & 1 deletion packages/api/src/api/ProviderApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
type PowCaptchaSolutionResponse,
type ProcaptchaToken,
type Provider,
type ProviderApiInterface,
type ProviderRegistered,
type RandomProvider,
type ServerPowCaptchaVerifyRequestBodyType,
Expand All @@ -36,7 +37,10 @@ import {
} from "@prosopo/types";
import HttpClientBase from "./HttpClientBase.js";

export default class ProviderApi extends HttpClientBase implements ProviderApi {
export default class ProviderApi
extends HttpClientBase
implements ProviderApiInterface
{
private account: string;

constructor(providerUrl: string, account: string) {
Expand Down
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"test": "NODE_ENV=${NODE_ENV:-test}; npx vitest run --config ./vite.test.config.ts",
"cli": "node ./dist/cli.js",
"start": "node ./dist/cli.js --api",
"start:admin": "node ./dist/cli.js --api --adminApi",
"start:dev": "node ./dist/cli.js --api --dev"
},
"dependencies": {
Expand Down
8 changes: 4 additions & 4 deletions packages/cli/src/RateLimiter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@ export const getRateLimitConfig = () => {
windowMs: process.env.PROSOPO_SUBMIT_USER_EVENTS_WINDOW,
limit: process.env.PROSOPO_SUBMIT_USER_EVENTS_LIMIT,
},
[AdminApiPaths.BatchCommit]: {
windowMs: process.env.PROSOPO_BATCH_COMMIT_WINDOW,
limit: process.env.PROSOPO_BATCH_COMMIT_LIMIT,
},
[AdminApiPaths.UpdateDataset]: {
windowMs: process.env.PROSOPO_UPDATE_DATASET_WINDOW,
limit: process.env.PROSOPO_UPDATE_DATASET_LIMIT,
},
[AdminApiPaths.SiteKeyRegister]: {
windowMs: process.env.PROSOPO_SITE_KEY_REGISTER_WINDOW,
limit: process.env.PROSOPO_SITE_KEY_REGISTER_LIMIT,
},
[AdminApiPaths.ProviderDeregister]: {
windowMs: process.env.PROSOPO_PROVIDER_DEREGISTER_WINDOW,
limit: process.env.PROSOPO_PROVIDER_DEREGISTER_LIMIT,
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/src/argv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import yargs from "yargs";
import { hideBin } from "yargs/helpers";
import {
commandProviderSetDataset,
commandSiteKeyRegister,
commandStoreCaptchasExternally,
commandVersion,
} from "./commands/index.js";
Expand Down Expand Up @@ -45,6 +46,7 @@ export function processArgs(
} as const)
.command(commandProviderSetDataset(pair, config, { logger }))
.command(commandStoreCaptchasExternally(pair, config, { logger }))
.command(commandSiteKeyRegister(pair, config, { logger }))
.command(commandVersion(pair, config, { logger }))
.parse();
}
1 change: 1 addition & 0 deletions packages/cli/src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
export { default as commandProviderSetDataset } from "./providerSetDataset.js";
export { default as commandStoreCaptchasExternally } from "./storeCaptchasExternally.js";
export { default as commandVersion } from "./version.js";
export { default as commandSiteKeyRegister } from "./siteKeyRegister.js";
53 changes: 53 additions & 0 deletions packages/cli/src/commands/siteKeyRegister.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2021-2024 Prosopo (UK) Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import type { KeyringPair } from "@polkadot/keyring/types";
import { LogLevel, type Logger, getLogger } from "@prosopo/common";
import { ProviderEnvironment } from "@prosopo/env";
import { Tasks } from "@prosopo/provider";
import type { ProsopoConfigOutput } from "@prosopo/types";
import type { ArgumentsCamelCase, Argv } from "yargs";
import { validateSiteKey } from "./validators.js";

export default (
pair: KeyringPair,
config: ProsopoConfigOutput,
cmdArgs?: { logger?: Logger },
) => {
const logger =
cmdArgs?.logger || getLogger(LogLevel.enum.info, "cli.dapp_register");

return {
command: "site_key_register <sitekey>",
describe: "Register a Site Key",
builder: (yargs: Argv) =>
yargs.positional("sitekey", {
type: "string" as const,
demandOption: true,
desc: "The AccountId of the application to register the Site Key with",
} as const),
handler: async (argv: ArgumentsCamelCase) => {
try {
const env = new ProviderEnvironment(config, pair);
await env.isReady();
const siteKey = argv.sitekey;
const tasks = new Tasks(env);
await tasks.clientTaskManager.registerSiteKey(siteKey as string);
logger.info(`Site Key ${argv.sitekey} registered`);
} catch (err) {
logger.error(err);
}
},
middlewares: [validateSiteKey],
};
};
8 changes: 8 additions & 0 deletions packages/cli/src/commands/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ export const validateAddress = (
return { address };
};

export const validateSiteKey = (
argv: ArgumentsCamelCase,
): { sitekey: string } => {
const sitekey = encodeStringAddress(argv.sitekey as string);

return { sitekey };
};

export const validateValue = (argv: ArgumentsCamelCase) => {
if (typeof argv.value !== "number") {
throw new ProsopoEnvError("CLI.PARAMETER_ERROR", {
Expand Down
6 changes: 6 additions & 0 deletions packages/common/src/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,9 @@ export class Loggable {
this.#logger = logger;
}
}

export const logError = (err: unknown, logger: Logger): void => {
logger.error(
typeof err === "object" && err ? ("stack" in err ? err.stack : err) : err,
);
};
17 changes: 15 additions & 2 deletions packages/database/src/databases/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import {
type ClientRecord,
ClientRecordSchema,
DatasetRecordSchema,
type IDatabase,
type IProviderDatabase,
type IUserDataSlim,
PendingRecordSchema,
type PoWCaptchaRecord,
Expand Down Expand Up @@ -126,7 +126,10 @@ const PROVIDER_TABLES = [
},
];

export class ProviderDatabase extends MongoDatabase implements IDatabase {
export class ProviderDatabase
extends MongoDatabase
implements IProviderDatabase
{
tables = {} as Tables<TableNames>;

constructor(
Expand Down Expand Up @@ -1256,4 +1259,14 @@ export class ProviderDatabase extends MongoDatabase implements IDatabase {
});
await this.tables?.client.bulkWrite(ops);
}

/**
* @description Get a client record
*/
async getClientRecord(account: string): Promise<ClientRecord | undefined> {
const doc = await this.tables?.client
.findOne({ account })
.lean<ClientRecord>();
return doc ? doc : undefined;
}
}
Loading

0 comments on commit 346cdf5

Please sign in to comment.