mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-15 20:17:22 +00:00
Merge remote-tracking branch 'origin/release/0.20' into feat/postgres-fc
# Conflicts: # app/src/core/utils/runtime.ts
This commit is contained in:
@@ -261,3 +261,77 @@ export default {
|
||||
```
|
||||
|
||||
|
||||
### `emailOTP`
|
||||
|
||||
<Callout type="warning">
|
||||
Make sure to setup proper permissions to restrict reading from the OTP entity. Also, this plugin requires the `email` driver to be registered.
|
||||
</Callout>
|
||||
|
||||
|
||||
A plugin that adds email OTP functionality to your app. It will add two endpoints to your app:
|
||||
- `POST /api/auth/otp/login` to login a user with an OTP code
|
||||
- `POST /api/auth/otp/register` to register a user with an OTP code
|
||||
|
||||
Both endpoints accept a JSON body with `email` (required) and `code` (optional). If `code` is provided, the OTP code will be validated and the user will be logged in or registered. If `code` is not provided, a new OTP code will be generated and sent to the user's email.
|
||||
|
||||
For example, to login an existing user with an OTP code, two requests are needed. The first one only with the email to generate and send the OTP code, and the second to send the users' email along with the OTP code. The last request will authenticate the user.
|
||||
|
||||
```http title="Generate OTP code to login"
|
||||
POST /api/auth/otp/login
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"email": "test@example.com"
|
||||
}
|
||||
```
|
||||
|
||||
If the user exists, an email will be sent with the OTP code, and the response will be a `201 Created`.
|
||||
|
||||
```http title="Login with OTP code"
|
||||
POST /api/auth/otp/login
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"email": "test@example.com",
|
||||
"code": "123456"
|
||||
}
|
||||
```
|
||||
|
||||
If the code is valid, the user will be authenticated by sending a `Set-Cookie` header and a body property `token` with the JWT token (equally to the login endpoint).
|
||||
|
||||
|
||||
```typescript title="bknd.config.ts"
|
||||
import { emailOTP } from "bknd/plugins";
|
||||
import { resendEmail } from "bknd";
|
||||
|
||||
export default {
|
||||
options: {
|
||||
drivers: {
|
||||
// an email driver is required
|
||||
email: resendEmail({ /* ... */}),
|
||||
},
|
||||
plugins: [
|
||||
// all options are optional
|
||||
emailOTP({
|
||||
// the base path for the API endpoints
|
||||
apiBasePath: "/api/auth/otp",
|
||||
// the TTL for the OTP tokens in seconds
|
||||
ttl: 600,
|
||||
// the name of the OTP entity
|
||||
entity: "users_otp",
|
||||
// customize the email content
|
||||
generateEmail: (otp) => ({
|
||||
subject: "OTP Code",
|
||||
body: `Your OTP code is: ${otp.code}`,
|
||||
}),
|
||||
// customize the code generation
|
||||
generateCode: (user) => {
|
||||
return Math.floor(100000 + Math.random() * 900000).toString();
|
||||
},
|
||||
})
|
||||
],
|
||||
},
|
||||
} satisfies BkndConfig;
|
||||
```
|
||||
|
||||
<AutoTypeTable path="../app/src/plugins/auth/email-otp.plugin.ts" name="EmailOTPPluginOptions" />
|
||||
|
||||
@@ -40,12 +40,6 @@ bun add bknd
|
||||
|
||||
</Tabs>
|
||||
|
||||
<Callout type="info">
|
||||
The guide below assumes you're using Astro v4. We've experienced issues with
|
||||
Astro DB using v5, see [this
|
||||
issue](https://github.com/withastro/astro/issues/12474).
|
||||
</Callout>
|
||||
|
||||
For the Astro integration to work, you also need to [add the react integration](https://docs.astro.build/en/guides/integrations-guide/react/):
|
||||
|
||||
```bash
|
||||
@@ -159,7 +153,7 @@ Create a new catch-all route at `src/pages/admin/[...admin].astro`:
|
||||
import { Admin } from "bknd/ui";
|
||||
import "bknd/dist/styles.css";
|
||||
|
||||
import { getApi } from "bknd/adapter/astro";
|
||||
import { getApi } from "../../../bknd.ts"; // /src/bknd.ts
|
||||
|
||||
const api = await getApi(Astro, { mode: "dynamic" });
|
||||
const user = api.getUser();
|
||||
|
||||
@@ -213,9 +213,9 @@ To use it, you have to wrap your configuration in a mode helper, e.g. for `code`
|
||||
import { code, type CodeMode } from "bknd/modes";
|
||||
import { type BunBkndConfig, writer } from "bknd/adapter/bun";
|
||||
|
||||
const config = {
|
||||
export default code<BunBkndConfig>({
|
||||
// some normal bun bknd config
|
||||
connection: { url: "file:test.db" },
|
||||
connection: { url: "file:data.db" },
|
||||
// ...
|
||||
// a writer is required, to sync the types
|
||||
writer,
|
||||
@@ -227,9 +227,7 @@ const config = {
|
||||
force: true,
|
||||
drop: true,
|
||||
}
|
||||
} satisfies CodeMode<BunBkndConfig>;
|
||||
|
||||
export default code(config);
|
||||
});
|
||||
```
|
||||
|
||||
Similarily, for `hybrid` mode:
|
||||
@@ -238,9 +236,9 @@ Similarily, for `hybrid` mode:
|
||||
import { hybrid, type HybridMode } from "bknd/modes";
|
||||
import { type BunBkndConfig, writer, reader } from "bknd/adapter/bun";
|
||||
|
||||
const config = {
|
||||
export default hybrid<BunBkndConfig>({
|
||||
// some normal bun bknd config
|
||||
connection: { url: "file:test.db" },
|
||||
connection: { url: "file:data.db" },
|
||||
// ...
|
||||
// reader/writer are required, to sync the types and config
|
||||
writer,
|
||||
@@ -262,7 +260,5 @@ const config = {
|
||||
force: true,
|
||||
drop: true,
|
||||
},
|
||||
} satisfies HybridMode<BunBkndConfig>;
|
||||
|
||||
export default hybrid(config);
|
||||
});
|
||||
```
|
||||
Reference in New Issue
Block a user