Skip to content

Commit 60b81b6

Browse files
committed
docs: fix Python version typo and improve formatting
- Correct Python version requirement from "Python 10" to "Python 3.10" - Add recommendation to use `uv` for Python version installation - Improve line wrapping and formatting consistency across documentation - Break long lines in API security features and response descriptions for better readability The main fix addresses a critical typo in the prerequisites section that could confuse contributors about the required Python version. Signed-off-by: Grant Ramsay <seapagan@gmail.com>
1 parent 980ce6a commit 60b81b6

2 files changed

Lines changed: 48 additions & 22 deletions

File tree

CONTRIBUTING.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ development process and documentation.
3333

3434
## Prerequisites
3535

36-
Since this is a [Python](https://www.python.org/) project, you will need to
37-
have Python installed on your machine. You can download the latest version of
38-
Python from the [official website](https://www.python.org/downloads/) or using
39-
your Operating system's package manager. This project requires **Python 10** or
36+
Since this is a [Python](https://www.python.org/) project, you will need to have
37+
Python installed on your machine. You can download the latest version of Python
38+
from the [official website](https://www.python.org/downloads/) or using your
39+
Operating system's package manager. This project requires **Python 3.10** or
4040
higher.
4141

4242
I'd recommend using
@@ -45,7 +45,8 @@ I'd recommend using
4545
Mac OS X. For Windows, you can use the
4646
[pyenv-win](https://github.com/pyenv-win/pyenv-win) port. See
4747
[here](https://github.com/pyenv-win/pyenv-win#installation ) for installation
48-
instructions.
48+
instructions. Of course you can also (and probably the best way) use `uv` to
49+
install a python version much easier, though `pyenv` works with `uv` also.
4950

5051
- We use [uv](https://docs.astral.sh/uv/) to manage our dependencies. You should
5152
have this installed as well. You can install `uv` by following the instructions

docs/reference/api.md

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,10 @@ Generates a new JWT token using a valid refresh token.
106106
**Security Features:**
107107

108108
- **Format Validation**: Fast syntactic check before expensive crypto operations
109-
- **Length Validation**: Tokens exceeding 1024 chars are rejected to prevent resource exhaustion
110-
- **Defense-in-depth**: Multiple validation layers (format, length, cryptographic signature, token type)
109+
- **Length Validation**: Tokens exceeding 1024 chars are rejected to prevent
110+
resource exhaustion
111+
- **Defense-in-depth**: Multiple validation layers (format, length,
112+
cryptographic signature, token type)
111113
- **Early Rejection**: Invalid formats fail fast with clear error messages
112114
- **Token Verification**: Tokens are cryptographically verified (JWT with HS256)
113115
- **Type Checking**: Only tokens with `typ="refresh"` are accepted
@@ -147,8 +149,10 @@ Verifies a user's email address using the token sent via email.
147149
**Security Features:**
148150

149151
- **Format Validation**: Fast syntactic check before expensive crypto operations
150-
- **Length Validation**: Tokens exceeding 1024 chars are rejected to prevent resource exhaustion
151-
- **Defense-in-depth**: Multiple validation layers (format, length, cryptographic signature, token type)
152+
- **Length Validation**: Tokens exceeding 1024 chars are rejected to prevent
153+
resource exhaustion
154+
- **Defense-in-depth**: Multiple validation layers (format, length,
155+
cryptographic signature, token type)
152156
- **Early Rejection**: Invalid formats fail fast with clear error messages
153157
- **Token Verification**: Tokens are cryptographically verified (JWT with HS256)
154158
- **Type Checking**: Only tokens with `typ="verify"` are accepted
@@ -202,20 +206,24 @@ Initiates a password reset by sending a reset email to the user.
202206

203207
**Endpoint:** `GET /reset-password/?code={token}`
204208

205-
Displays an HTML form for resetting password OR redirects to a custom frontend. This is the endpoint linked in password reset emails.
209+
Displays an HTML form for resetting password OR redirects to a custom frontend.
210+
This is the endpoint linked in password reset emails.
206211

207212
**Query Parameters:**
208213

209214
- `code` (required): Password reset token from email
210215

211216
**Response:**
212217

213-
- `302 Redirect` (if `FRONTEND_URL` is configured) - Redirects to `{FRONTEND_URL}/reset-password?code={token}`
214-
- `200 OK` (HTML) (if `FRONTEND_URL` is not set) - Shows built-in password reset form
218+
- `302 Redirect` (if `FRONTEND_URL` is configured) - Redirects to
219+
`{FRONTEND_URL}/reset-password?code={token}`
220+
- `200 OK` (HTML) (if `FRONTEND_URL` is not set) - Shows built-in password reset
221+
form
215222

216223
**Built-in Form Behavior (no FRONTEND_URL):**
217224

218225
Returns an HTML page with:
226+
219227
- Password reset form (if token is valid)
220228
- Error message (if token is invalid/expired)
221229

@@ -234,40 +242,49 @@ Returns an HTML page with:
234242

235243
**Security Features:**
236244

237-
- **URL Encoding**: Reset tokens are URL-encoded before redirect to prevent injection attacks
238-
- **Length Validation**: Tokens are validated for reasonable size to prevent resource exhaustion
239-
- **Redirect Safety**: When `FRONTEND_URL` is set, redirects only go to the configured domain with validated tokens
245+
- **URL Encoding**: Reset tokens are URL-encoded before redirect to prevent
246+
injection attacks
247+
- **Length Validation**: Tokens are validated for reasonable size to prevent
248+
resource exhaustion
249+
- **Redirect Safety**: When `FRONTEND_URL` is set, redirects only go to the
250+
configured domain with validated tokens
240251
- **Token Verification**: Tokens are cryptographically verified (JWT with HS256)
241252
- **Expiration**: Reset tokens expire after 30 minutes
242253

243254
**Notes:**
244255

245-
- **With custom frontend**: Set `FRONTEND_URL` in settings/env to redirect users to your app
256+
- **With custom frontend**: Set `FRONTEND_URL` in settings/env to redirect users
257+
to your app
246258
- **Without custom frontend**: Leave `FRONTEND_URL` unset to use built-in form
247259
- Validates token before displaying the form (when using built-in form)
248260
- Form submits to `POST /reset-password/`
249-
- Provides seamless integration with custom frontends while maintaining standalone functionality
261+
- Provides seamless integration with custom frontends while maintaining
262+
standalone functionality
250263

251264
**Configuration:**
252265

253266
To use with a custom frontend, set in `.env`:
254-
```
267+
268+
```ini
255269
FRONTEND_URL=https://app.example.com
256270
```
257271

258272
Your frontend should:
273+
259274
1. Handle the route `/reset-password`
260275
2. Extract the `code` query parameter
261276
3. Display a custom password reset form
262-
4. POST to backend `/reset-password/` with JSON: `{"code": "...", "new_password": "..."}`
277+
4. POST to backend `/reset-password/` with JSON: `{"code": "...",
278+
"new_password": "..."}`
263279

264280
---
265281

266282
### Reset Password (API)
267283

268284
**Endpoint:** `POST /reset-password/`
269285

270-
Resets a user's password using the token received via email. Accepts both JSON (for API clients) and form data (from HTML form).
286+
Resets a user's password using the token received via email. Accepts both JSON
287+
(for API clients) and form data (from HTML form).
271288

272289
**Request Body (JSON):**
273290

@@ -280,7 +297,7 @@ Resets a user's password using the token received via email. Accepts both JSON (
280297

281298
**Request Body (Form Data):**
282299

283-
```
300+
```ini
284301
code=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
285302
new_password=mynewsecurepassword456
286303
```
@@ -339,6 +356,7 @@ Returns the currently authenticated user's information.
339356
```
340357

341358
**Notes:**
359+
342360
- Non-admin users only see their own basic information
343361
- Admin users can use `/users/` to see full details
344362

@@ -373,6 +391,7 @@ Get all users or a specific user by their ID.
373391
```
374392

375393
**Notes:**
394+
376395
- If `user_id` is omitted, returns all users
377396
- If `user_id` is provided, returns single user object (not array)
378397

@@ -389,7 +408,8 @@ Search for users with various criteria.
389408
**Query Parameters:**
390409

391410
- `search_term` (required): Search query string
392-
- `field` (optional): Field to search ("all", "email", "first_name", "last_name") - default: "all"
411+
- `field` (optional): Field to search ("all", "email", "first_name",
412+
"last_name") - default: "all"
393413
- `exact_match` (optional): Use exact matching instead of partial - default: false
394414
- `page` (optional): Page number (min: 1, default: 1)
395415
- `size` (optional): Items per page (min: 1, max: 100, default: 50)
@@ -452,6 +472,7 @@ Update the specified user's data.
452472
```
453473

454474
**Notes:**
475+
455476
- Users can edit their own profile
456477
- Admins can edit any user's profile
457478

@@ -480,6 +501,7 @@ Change the password for the specified user.
480501
**Response:** `204 No Content`
481502

482503
**Notes:**
504+
483505
- Users can change their own password
484506
- Admins can change any user's password
485507

@@ -516,6 +538,7 @@ Ban the specified user. Banned users cannot login or access protected routes.
516538
**Response:** `204 No Content`
517539

518540
**Notes:**
541+
519542
- Admins cannot ban themselves
520543
- Banned users cannot reset passwords or access any authenticated endpoints
521544

@@ -552,6 +575,7 @@ Permanently delete the specified user.
552575
**Response:** `204 No Content`
553576

554577
**Notes:**
578+
555579
- This action is permanent and cannot be undone
556580
- All associated API keys will also be deleted
557581

@@ -683,6 +707,7 @@ Update an API key's name or active status.
683707
```
684708

685709
**Notes:**
710+
686711
- Both fields are optional in the request
687712
- Setting `is_active` to `false` disables the key without deleting it
688713

0 commit comments

Comments
 (0)