Update docs
This commit is contained in:
@@ -23,8 +23,8 @@ Before you can integrate Duckity into your application, you'll need to have the
|
||||
|
||||
1. An application,
|
||||
2. CORS origins set up pointing to your application's origin(s),
|
||||
3. At least one protection profile created in that application, and
|
||||
4. The ID of the protection profiles to use
|
||||
3. At least one policy created in that application, and
|
||||
4. The ID of the policies to use
|
||||
|
||||
If you're missing either of those, head over to the [Duckity Dashboard](https://app.duckity.com) or
|
||||
read the [Quick Start](/quick-start) guide to learn how to set those up.
|
||||
@@ -78,7 +78,7 @@ Once you have the SDK installed, you can request a challenge whenever you need i
|
||||
import duckity from "@duckity/js";
|
||||
|
||||
/// Slow! Runs in a web worker, yet don't let it block code below unless necessary.
|
||||
let solution: string = await duckity.solve(PROTECTION_PROFILE_ID);
|
||||
let solution: string = await duckity.solve(POLICY_ID);
|
||||
```
|
||||
|
||||
### Validate a Challenge [step]
|
||||
@@ -86,18 +86,18 @@ let solution: string = await duckity.solve(PROTECTION_PROFILE_ID);
|
||||
Send the solution token to your backend server any way you want. A header or parameter in a JSON
|
||||
field will work.
|
||||
|
||||
Once in the server, you'll need the client's IP, their submitted solution token, the protection
|
||||
profile's ID, and the application secret.
|
||||
Once in the server, you'll need the client's IP, their submitted solution token, the policy's ID,
|
||||
and the application secret.
|
||||
|
||||
```ts
|
||||
import * as duckity from "@duckity/js";
|
||||
|
||||
let applicationSecret: string;
|
||||
let protectionProfileId: string;
|
||||
let policyId: string;
|
||||
let clientIp: string;
|
||||
let solution: string;
|
||||
|
||||
let isValid = await duckity.validate(solution, clientIp, applicationSecret, protectionProfileId);
|
||||
let isValid = await duckity.validate(solution, clientIp, applicationSecret, policyId);
|
||||
|
||||
if (isValid) {
|
||||
// Keep processing the request.
|
||||
@@ -144,7 +144,7 @@ wait.
|
||||
<script type="module">
|
||||
import * as duckity from "https://esm.sh/@duckity/js";
|
||||
|
||||
const PROTECTION_PROFILE_ID = "<your-protection-profile-id>";
|
||||
const POLICY_ID = "<your-policy-id>";
|
||||
|
||||
const form = document.getElementById("form");
|
||||
const submitButton = document.getElementById("submit-button");
|
||||
@@ -153,7 +153,7 @@ wait.
|
||||
// A Promise<string>, it will solve a challenge in the background while the user logs
|
||||
// in. Do not `await` it here, it will prevent the `form.addEventListener()` call from
|
||||
// running until the challenge is solved, which takes some time.
|
||||
let solutionPromise = duckity.solve(PROTECTION_PROFILE_ID);
|
||||
let solutionPromise = duckity.solve(POLICY_ID);
|
||||
|
||||
form.addEventListener("submit", async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
+20
-20
@@ -19,8 +19,8 @@ event loop's version of it.
|
||||
Before you can integrate Duckity into your application, you'll need to have the following:
|
||||
|
||||
1. An application,
|
||||
2. At least one protection profile created in that application, and
|
||||
3. The ID of the protection profiles to use
|
||||
2. At least one policy created in that application, and
|
||||
3. The ID of the policies to use
|
||||
|
||||
If you're missing either of those, head over to the [Duckity Dashboard](https://app.duckity.com) or
|
||||
read the [Quick Start](/quick-start) guide to learn how to set those up.
|
||||
@@ -52,14 +52,14 @@ Install the SDK from PyPI using your favorite package manager:
|
||||
|
||||
### Solve a Challenge [step]
|
||||
|
||||
Solving a challenge only requires a protection profile ID.
|
||||
Solving a challenge only requires a policy ID.
|
||||
|
||||
<Tabs items={["Async", "Sync"]} groupId="python-sync" persist>
|
||||
<Tab value="Async" id="async">
|
||||
```py
|
||||
import duckity
|
||||
|
||||
solution: str = await duckity.solve(PROTECTION_PROFILE_ID)
|
||||
solution: str = await duckity.solve(POLICY_ID)
|
||||
```
|
||||
|
||||
The CPU-intensive part of solving the challenge is done in a `ProcessPoolExecutor()`.
|
||||
@@ -71,7 +71,7 @@ Solving a challenge only requires a protection profile ID.
|
||||
|
||||
import duckity
|
||||
|
||||
solution: str = asyncio.run(duckity.solve(PROTECTION_PROFILE_ID))
|
||||
solution: str = asyncio.run(duckity.solve(POLICY_ID))
|
||||
```
|
||||
|
||||
The CPU-intensive part of solving the challenge is done in a `ProcessPoolExecutor()`. The
|
||||
@@ -90,7 +90,7 @@ To validate a solution token, you'll need 4 things:
|
||||
1. The solution token,
|
||||
2. The IP of the client that submitted the solution,
|
||||
3. The application's secret, and
|
||||
4. The protection profile's ID.
|
||||
4. The policy's ID.
|
||||
|
||||
Once you have them, you can validate a solution token as follows:
|
||||
|
||||
@@ -102,10 +102,10 @@ Once you have them, you can validate a solution token as follows:
|
||||
solution: str
|
||||
client_ip: str
|
||||
application_secret: str
|
||||
protection_profile_id: str
|
||||
policy_id: str
|
||||
|
||||
is_valid: bool = await duckity.validate(
|
||||
solution, client_ip, application_secret, protection_profile_id
|
||||
solution, client_ip, application_secret, policy_id
|
||||
)
|
||||
```
|
||||
</Tab>
|
||||
@@ -118,10 +118,10 @@ Once you have them, you can validate a solution token as follows:
|
||||
solution: str
|
||||
client_ip: str
|
||||
application_secret: str
|
||||
protection_profile_id: str
|
||||
policy_id: str
|
||||
|
||||
is_valid: bool = asyncio.run(
|
||||
duckity.validate(solution, client_ip, application_secret, protection_profile_id)
|
||||
duckity.validate(solution, client_ip, application_secret, policy_id)
|
||||
)
|
||||
```
|
||||
</Tab>
|
||||
@@ -154,7 +154,7 @@ import duckity
|
||||
|
||||
|
||||
async def login():
|
||||
solution_task = asyncio.create_task(duckity.solve(PROTECTION_PROFILE_ID))
|
||||
solution_task = asyncio.create_task(duckity.solve(POLICY_ID))
|
||||
|
||||
email = await asyncio.to_thread(input, "Enter your email: ")
|
||||
password = await asyncio.to_thread(getpass.getpass, "Enter your password (hidden): ")
|
||||
@@ -191,7 +191,7 @@ from pydantic import BaseModel
|
||||
dotenv.load_dotenv(override=True)
|
||||
|
||||
|
||||
PROTECTION_PROFILE_ID = os.environ["DUCKITY_PROTECTION_PROFILE_ID"]
|
||||
POLICY_ID = os.environ["DUCKITY_POLICY_ID"]
|
||||
APPLICATION_SECRET = os.environ["DUCKITY_APPLICATION_SECRET"]
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ async def protected(request: Request, payload: RequestBodySchema):
|
||||
payload.solution,
|
||||
request.client.host, # Make sure to take into account X-Forwarded-For if behind a reverse proxy.
|
||||
APPLICATION_SECRET,
|
||||
PROTECTION_PROFILE_ID
|
||||
POLICY_ID
|
||||
)
|
||||
|
||||
if not is_valid:
|
||||
@@ -240,7 +240,7 @@ dotenv.load_dotenv(override=True)
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
PROTECTION_PROFILE_ID = os.environ["DUCKITY_PROTECTION_PROFILE_ID"]
|
||||
POLICY_ID = os.environ["DUCKITY_POLICY_ID"]
|
||||
APPLICATION_SECRET = os.environ["DUCKITY_APPLICATION_SECRET"]
|
||||
|
||||
|
||||
@@ -257,7 +257,7 @@ async def protected():
|
||||
solution,
|
||||
client_ip,
|
||||
APPLICATION_SECRET,
|
||||
PROTECTION_PROFILE_ID,
|
||||
POLICY_ID,
|
||||
)
|
||||
|
||||
if not is_valid:
|
||||
@@ -300,7 +300,7 @@ async def protected(request):
|
||||
solution,
|
||||
client_ip,
|
||||
settings.DUCKITY_APPLICATION_SECRET,
|
||||
settings.DUCKITY_PROTECTION_PROFILE_ID,
|
||||
settings.DUCKITY_POLICY_ID,
|
||||
)
|
||||
|
||||
if not is_valid:
|
||||
@@ -339,7 +339,7 @@ async def protected(request, payload: RequestBodySchema):
|
||||
payload.solution,
|
||||
client_ip,
|
||||
settings.DUCKITY_APPLICATION_SECRET,
|
||||
settings.DUCKITY_PROTECTION_PROFILE_ID,
|
||||
settings.DUCKITY_POLICY_ID,
|
||||
)
|
||||
|
||||
if not is_valid:
|
||||
@@ -378,7 +378,7 @@ class ProtectedView(APIView):
|
||||
serializer.validated_data["solution"],
|
||||
client_ip,
|
||||
settings.DUCKITY_APPLICATION_SECRET,
|
||||
settings.DUCKITY_PROTECTION_PROFILE_ID,
|
||||
settings.DUCKITY_POLICY_ID,
|
||||
)
|
||||
|
||||
if not is_valid:
|
||||
@@ -405,7 +405,7 @@ import strawberry
|
||||
dotenv.load_dotenv(override=True)
|
||||
|
||||
|
||||
PROTECTION_PROFILE_ID = os.environ["DUCKITY_PROTECTION_PROFILE_ID"]
|
||||
POLICY_ID = os.environ["DUCKITY_POLICY_ID"]
|
||||
APPLICATION_SECRET = os.environ["DUCKITY_APPLICATION_SECRET"]
|
||||
|
||||
|
||||
@@ -430,7 +430,7 @@ class Mutation:
|
||||
solution,
|
||||
client_ip,
|
||||
DUCKITY_APPLICATION_SECRET,
|
||||
DUCKITY_PROTECTION_PROFILE_ID,
|
||||
DUCKITY_POLICY_ID,
|
||||
)
|
||||
|
||||
if not is_valid:
|
||||
|
||||
@@ -21,8 +21,8 @@ Before you can integrate Duckity into your application, you'll need to have the
|
||||
|
||||
1. An application,
|
||||
2. CORS origins set up pointing to your application's origin(s),
|
||||
3. At least one protection profile created in that application, and
|
||||
4. The ID of the protection profiles to use
|
||||
3. At least one policy created in that application, and
|
||||
4. The ID of the policies to use
|
||||
|
||||
If you're missing either of those, head over to the [Duckity Dashboard](https://app.duckity.com) or
|
||||
read the [Quick Start](/quick-start) guide to learn how to set those up.
|
||||
@@ -55,7 +55,7 @@ Use the hook as follows:
|
||||
import { useChallenge } from "@duckity/react";
|
||||
|
||||
function MyComponent() {
|
||||
const duckity = useChallenge(process.env.NEXT_PUBLIC_DUCKITY_PROTECTION_PROFILE_ID);
|
||||
const duckity = useChallenge(process.env.NEXT_PUBLIC_DUCKITY_POLICY_ID);
|
||||
}
|
||||
```
|
||||
</Tab>
|
||||
@@ -64,7 +64,7 @@ Use the hook as follows:
|
||||
import { useChallenge } from "@duckity/react";
|
||||
|
||||
function MyComponent() {
|
||||
const duckity = useChallenge(import.meta.env.VITE_DUCKITY_PROTECTION_PROFILE_ID);
|
||||
const duckity = useChallenge(import.meta.env.VITE_DUCKITY_POLICY_ID);
|
||||
}
|
||||
```
|
||||
</Tab>
|
||||
@@ -77,14 +77,14 @@ Use the hook as follows:
|
||||
export async function loader() {
|
||||
return json({
|
||||
ENV: {
|
||||
DUCKITY_PROTECTION_PROFILE_ID: process.env.DUCKITY_PROTECTION_PROFILE_ID,
|
||||
DUCKITY_POLICY_ID: process.env.DUCKITY_POLICY_ID,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function MyComponent() {
|
||||
const data = useLoaderData<typeof loader>();
|
||||
const duckity = useChallenge(data.ENV.DUCKITY_PROTECTION_PROFILE_ID);
|
||||
const duckity = useChallenge(data.ENV.DUCKITY_POLICY_ID);
|
||||
}
|
||||
```
|
||||
</Tab>
|
||||
@@ -93,7 +93,7 @@ Use the hook as follows:
|
||||
import { useChallenge } from "@duckity/react";
|
||||
|
||||
function MyComponent() {
|
||||
const duckity = useChallenge(process.env.GATSBY_DUCKITY_PROTECTION_PROFILE_ID);
|
||||
const duckity = useChallenge(process.env.GATSBY_DUCKITY_POLICY_ID);
|
||||
}
|
||||
```
|
||||
</Tab>
|
||||
@@ -102,7 +102,7 @@ Use the hook as follows:
|
||||
import { useChallenge } from "@duckity/react";
|
||||
|
||||
function MyComponent() {
|
||||
const duckity = useChallenge(process.env.EXPO_PUBLIC_DUCKITY_PROTECTION_PROFILE_ID);
|
||||
const duckity = useChallenge(process.env.EXPO_PUBLIC_DUCKITY_POLICY_ID);
|
||||
}
|
||||
```
|
||||
</Tab>
|
||||
@@ -111,7 +111,7 @@ Use the hook as follows:
|
||||
import { useChallenge } from "@duckity/react";
|
||||
|
||||
function MyComponent() {
|
||||
const duckity = useChallenge(import.meta.env.PUBLIC_DUCKITY_PROTECTION_PROFILE_ID);
|
||||
const duckity = useChallenge(import.meta.env.PUBLIC_DUCKITY_POLICY_ID);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
+15
-15
@@ -19,8 +19,8 @@ in case you want to use the `core` module later on.
|
||||
Before you can integrate Duckity into your application, you'll need to have the following:
|
||||
|
||||
1. An application,
|
||||
2. At least one protection profile created in that application, and
|
||||
3. The ID of the protection profiles to use
|
||||
2. At least one policy created in that application, and
|
||||
3. The ID of the policies to use
|
||||
|
||||
If you're missing either of those, head over to the [Duckity Dashboard](https://app.duckity.com) or
|
||||
read the [Quick Start](/quick-start) guide to learn how to set those up.
|
||||
@@ -40,7 +40,7 @@ cargo add duckity
|
||||
To get and solve a challenge, use `duckity::solve()` like follows:
|
||||
|
||||
```rs
|
||||
let solution: str = duckity::solve(PROTECTION_PROFILE_ID).await?;
|
||||
let solution: str = duckity::solve(POLICY_ID).await?;
|
||||
```
|
||||
|
||||
That's it! Once you have your solution token, you can send it over to your backend for validation.
|
||||
@@ -60,7 +60,7 @@ To validate a solution token, you'll need 4 things:
|
||||
1. The solution token,
|
||||
2. The IP of the client that submitted the solution,
|
||||
3. The application's secret, and
|
||||
4. The protection profile's ID.
|
||||
4. The policy's ID.
|
||||
|
||||
Once you have them, you can validate a solution token as follows:
|
||||
|
||||
@@ -69,7 +69,7 @@ let is_valid: bool = duckity::validate(
|
||||
solution,
|
||||
client_ip,
|
||||
APPLICATION_SECRET,
|
||||
PROTECTION_PROFILE_ID
|
||||
POLICY_ID
|
||||
)
|
||||
.await?;
|
||||
```
|
||||
@@ -95,7 +95,7 @@ challenge while the user is filling up their username and password. For example:
|
||||
```rs
|
||||
use std::io::{self, Write};
|
||||
|
||||
const PROTECTION_PROFILE_ID: &str = "<your-own-protection-profile-id>";
|
||||
const POLICY_ID: &str = "<your-own-policy-id>";
|
||||
|
||||
struct Credentials {
|
||||
email: String,
|
||||
@@ -104,7 +104,7 @@ struct Credentials {
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
let solution_task = tokio::spawn(duckity::solve(PROTECTION_PROFILE_ID).into_future());
|
||||
let solution_task = tokio::spawn(duckity::solve(POLICY_ID).into_future());
|
||||
|
||||
let credentials = tokio::task::spawn_blocking(|| {
|
||||
let mut email = String::new();
|
||||
@@ -169,11 +169,11 @@ simple. For example, the following snippet shows how to solve and validate a cha
|
||||
```rs
|
||||
use async_compat::CompatExt;
|
||||
|
||||
const PROTECTION_PROFILE_ID: &str = "<insert-your-protection-profile-here>";
|
||||
const POLICY_ID: &str = "<insert-your-policy-here>";
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
smol::block_on(async {
|
||||
let solution = duckity::solve(PROTECTION_PROFILE_ID).into_future().compat().await?;
|
||||
let solution = duckity::solve(POLICY_ID).into_future().compat().await?;
|
||||
|
||||
Ok(())
|
||||
})
|
||||
@@ -199,7 +199,7 @@ use tokio::net::TcpListener;
|
||||
|
||||
// In an actual application, make these two configurable. `clap` is a good tool for that.
|
||||
const APPLICATION_SECRET: &str = "<your-application-secret>";
|
||||
const PROTECTION_PROFILE_ID: &str = "<your-protection-profile-id>";
|
||||
const POLICY_ID: &str = "<your-policy-id>";
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
@@ -229,7 +229,7 @@ async fn handler(
|
||||
payload.solution,
|
||||
addr.ip(),
|
||||
APPLICATION_SECRET,
|
||||
PROTECTION_PROFILE_ID,
|
||||
POLICY_ID,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -256,7 +256,7 @@ use warp::{Filter, Reply};
|
||||
|
||||
// In an actual application, make these two configurable. `clap` is a good tool for that.
|
||||
const APPLICATION_SECRET: &str = "<your-application-secret>";
|
||||
const PROTECTION_PROFILE_ID: &str = "<your-protection-profile-id>";
|
||||
const POLICY_ID: &str = "<your-policy-id>";
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
@@ -287,7 +287,7 @@ async fn handler(
|
||||
payload.solution,
|
||||
addr.ip(),
|
||||
APPLICATION_SECRET,
|
||||
PROTECTION_PROFILE_ID,
|
||||
POLICY_ID,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -317,7 +317,7 @@ use serde::Deserialize;
|
||||
|
||||
// In an actual application, make these two configurable. `clap` is a good tool for that.
|
||||
const APPLICATION_SECRET: &str = "<your-application-secret>";
|
||||
const PROTECTION_PROFILE_ID: &str = "<your-protection-profile-id>";
|
||||
const POLICY_ID: &str = "<your-policy-id>";
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
@@ -342,7 +342,7 @@ async fn protected(req: HttpRequest, payload: Json<ProtectedRequestPayload>) ->
|
||||
payload.solution.clone(),
|
||||
addr.ip(),
|
||||
APPLICATION_SECRET,
|
||||
PROTECTION_PROFILE_ID,
|
||||
POLICY_ID,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
Reference in New Issue
Block a user