authforge-sdk 1.2.0__tar.gz → 1.2.1__tar.gz
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.
- {authforge_sdk-1.2.0/authforge_sdk.egg-info → authforge_sdk-1.2.1}/PKG-INFO +4 -4
- {authforge_sdk-1.2.0 → authforge_sdk-1.2.1}/README.md +3 -3
- {authforge_sdk-1.2.0 → authforge_sdk-1.2.1}/authforge.py +16 -3
- {authforge_sdk-1.2.0 → authforge_sdk-1.2.1/authforge_sdk.egg-info}/PKG-INFO +4 -4
- {authforge_sdk-1.2.0 → authforge_sdk-1.2.1}/pyproject.toml +1 -1
- {authforge_sdk-1.2.0 → authforge_sdk-1.2.1}/LICENSE +0 -0
- {authforge_sdk-1.2.0 → authforge_sdk-1.2.1}/authforge_sdk.egg-info/SOURCES.txt +0 -0
- {authforge_sdk-1.2.0 → authforge_sdk-1.2.1}/authforge_sdk.egg-info/dependency_links.txt +0 -0
- {authforge_sdk-1.2.0 → authforge_sdk-1.2.1}/authforge_sdk.egg-info/requires.txt +0 -0
- {authforge_sdk-1.2.0 → authforge_sdk-1.2.1}/authforge_sdk.egg-info/top_level.txt +0 -0
- {authforge_sdk-1.2.0 → authforge_sdk-1.2.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: authforge-sdk
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: Official Python SDK for AuthForge — credit-based license key authentication with Ed25519-verified responses.
|
|
5
5
|
Author: AuthForge
|
|
6
6
|
License: MIT
|
|
@@ -110,7 +110,7 @@ client = AuthForgeClient(
|
|
|
110
110
|
| Parameter | Type | Default | Description |
|
|
111
111
|
|---|---|---|---|
|
|
112
112
|
| `app_id` | str | required | Your application ID from the AuthForge dashboard |
|
|
113
|
-
| `app_secret` | str | required | Your application secret from the AuthForge dashboard |
|
|
113
|
+
| `app_secret` | str | required for online APIs; `None` / `""` for `login_from_file` only | Your application secret from the AuthForge dashboard. Do not ship it in air-gapped binaries. |
|
|
114
114
|
| `public_key` | `str \| Sequence[str]` | required | App Ed25519 public key(s) (base64) from dashboard. Pass one key, a list of keys, or a comma-separated string to trust multiple keys during rotation (see [Key rotation](#key-rotation)). |
|
|
115
115
|
| `heartbeat_mode` | `str \| None` | `None` | Deprecated shim (see [Migrating from heartbeat_mode](#migrating-from-heartbeat_mode)). Use `online_heartbeat` instead. |
|
|
116
116
|
| `heartbeat_interval` | int | `900` | Seconds between background checks (minimum `10`; default 15 min). Applies to both grace period checks and online check-ins. |
|
|
@@ -159,7 +159,7 @@ Tune `ttl_seconds` to set the grace period duration (server default 24h, clamped
|
|
|
159
159
|
|
|
160
160
|
## Offline license files (`.authforge`)
|
|
161
161
|
|
|
162
|
-
For machines that never connect to the internet, the operator mints a **signed offline license file** in the AuthForge dashboard (License page -> *Mint .authforge file*) or via `POST /v1/licenses/{licenseKey}/offline-files`. The file is a standalone Ed25519-signed document; the SDK verifies it with **only** your app public key and the machine HWID. It never contacts AuthForge and never starts online check-ins.
|
|
162
|
+
For machines that never connect to the internet, the operator mints a **signed offline license file** in the AuthForge dashboard (License page -> *Mint .authforge file*) or via `POST /v1/licenses/{licenseKey}/offline-files`. The file is a standalone Ed25519-signed document; the SDK verifies it with **only** your app public key and the machine HWID. It never contacts AuthForge and never starts online check-ins. Pass `app_secret=None` (or `""`) so the air-gapped binary does not contain the App Secret.
|
|
163
163
|
|
|
164
164
|
| | Grace period (default) | Offline license file |
|
|
165
165
|
| --- | --- | --- |
|
|
@@ -174,7 +174,7 @@ from authforge import AuthForgeClient
|
|
|
174
174
|
|
|
175
175
|
client = AuthForgeClient(
|
|
176
176
|
app_id="YOUR_APP_ID",
|
|
177
|
-
app_secret=
|
|
177
|
+
app_secret=None, # login_from_file does not use the App Secret; do not ship it in air-gapped builds
|
|
178
178
|
public_key="YOUR_PUBLIC_KEY",
|
|
179
179
|
on_failure=lambda reason, exc: print(reason, exc),
|
|
180
180
|
)
|
|
@@ -82,7 +82,7 @@ client = AuthForgeClient(
|
|
|
82
82
|
| Parameter | Type | Default | Description |
|
|
83
83
|
|---|---|---|---|
|
|
84
84
|
| `app_id` | str | required | Your application ID from the AuthForge dashboard |
|
|
85
|
-
| `app_secret` | str | required | Your application secret from the AuthForge dashboard |
|
|
85
|
+
| `app_secret` | str | required for online APIs; `None` / `""` for `login_from_file` only | Your application secret from the AuthForge dashboard. Do not ship it in air-gapped binaries. |
|
|
86
86
|
| `public_key` | `str \| Sequence[str]` | required | App Ed25519 public key(s) (base64) from dashboard. Pass one key, a list of keys, or a comma-separated string to trust multiple keys during rotation (see [Key rotation](#key-rotation)). |
|
|
87
87
|
| `heartbeat_mode` | `str \| None` | `None` | Deprecated shim (see [Migrating from heartbeat_mode](#migrating-from-heartbeat_mode)). Use `online_heartbeat` instead. |
|
|
88
88
|
| `heartbeat_interval` | int | `900` | Seconds between background checks (minimum `10`; default 15 min). Applies to both grace period checks and online check-ins. |
|
|
@@ -131,7 +131,7 @@ Tune `ttl_seconds` to set the grace period duration (server default 24h, clamped
|
|
|
131
131
|
|
|
132
132
|
## Offline license files (`.authforge`)
|
|
133
133
|
|
|
134
|
-
For machines that never connect to the internet, the operator mints a **signed offline license file** in the AuthForge dashboard (License page -> *Mint .authforge file*) or via `POST /v1/licenses/{licenseKey}/offline-files`. The file is a standalone Ed25519-signed document; the SDK verifies it with **only** your app public key and the machine HWID. It never contacts AuthForge and never starts online check-ins.
|
|
134
|
+
For machines that never connect to the internet, the operator mints a **signed offline license file** in the AuthForge dashboard (License page -> *Mint .authforge file*) or via `POST /v1/licenses/{licenseKey}/offline-files`. The file is a standalone Ed25519-signed document; the SDK verifies it with **only** your app public key and the machine HWID. It never contacts AuthForge and never starts online check-ins. Pass `app_secret=None` (or `""`) so the air-gapped binary does not contain the App Secret.
|
|
135
135
|
|
|
136
136
|
| | Grace period (default) | Offline license file |
|
|
137
137
|
| --- | --- | --- |
|
|
@@ -146,7 +146,7 @@ from authforge import AuthForgeClient
|
|
|
146
146
|
|
|
147
147
|
client = AuthForgeClient(
|
|
148
148
|
app_id="YOUR_APP_ID",
|
|
149
|
-
app_secret=
|
|
149
|
+
app_secret=None, # login_from_file does not use the App Secret; do not ship it in air-gapped builds
|
|
150
150
|
public_key="YOUR_PUBLIC_KEY",
|
|
151
151
|
on_failure=lambda reason, exc: print(reason, exc),
|
|
152
152
|
)
|
|
@@ -360,7 +360,7 @@ class AuthForgeClient:
|
|
|
360
360
|
def __init__(
|
|
361
361
|
self,
|
|
362
362
|
app_id: str,
|
|
363
|
-
app_secret: str,
|
|
363
|
+
app_secret: Optional[str],
|
|
364
364
|
public_key: PublicKeyArg,
|
|
365
365
|
heartbeat_mode: Optional[str] = None,
|
|
366
366
|
heartbeat_interval: int = 900,
|
|
@@ -374,8 +374,12 @@ class AuthForgeClient:
|
|
|
374
374
|
) -> None:
|
|
375
375
|
if not app_id or not isinstance(app_id, str):
|
|
376
376
|
raise ValueError("app_id must be a non-empty string")
|
|
377
|
-
|
|
378
|
-
|
|
377
|
+
# Empty/None is valid for offline-only clients (login_from_file).
|
|
378
|
+
# Online APIs (login, validate_license, self_ban) still require a secret.
|
|
379
|
+
if app_secret is None:
|
|
380
|
+
app_secret = ""
|
|
381
|
+
elif not isinstance(app_secret, str):
|
|
382
|
+
raise ValueError("app_secret must be a string or None")
|
|
379
383
|
public_key_list = self._normalize_public_key_list(public_key)
|
|
380
384
|
if not public_key_list:
|
|
381
385
|
raise ValueError(
|
|
@@ -558,9 +562,16 @@ class AuthForgeClient:
|
|
|
558
562
|
except Exception:
|
|
559
563
|
pass
|
|
560
564
|
|
|
565
|
+
def _require_app_secret(self) -> None:
|
|
566
|
+
if not self.app_secret:
|
|
567
|
+
raise ValueError(
|
|
568
|
+
"app_secret is required for online APIs; omit it only when using login_from_file"
|
|
569
|
+
)
|
|
570
|
+
|
|
561
571
|
def login(self, license_key: str) -> bool:
|
|
562
572
|
if not license_key or not isinstance(license_key, str):
|
|
563
573
|
raise ValueError("license_key must be a non-empty string")
|
|
574
|
+
self._require_app_secret()
|
|
564
575
|
|
|
565
576
|
try:
|
|
566
577
|
self._validate_and_store(license_key)
|
|
@@ -575,6 +586,7 @@ class AuthForgeClient:
|
|
|
575
586
|
session state or starting the heartbeat thread."""
|
|
576
587
|
if not license_key or not isinstance(license_key, str):
|
|
577
588
|
raise ValueError("license_key must be a non-empty string")
|
|
589
|
+
self._require_app_secret()
|
|
578
590
|
try:
|
|
579
591
|
body: Dict[str, Any] = {
|
|
580
592
|
"appId": self.app_id,
|
|
@@ -661,6 +673,7 @@ class AuthForgeClient:
|
|
|
661
673
|
resolved_license = explicit_license or current_license
|
|
662
674
|
if not resolved_license:
|
|
663
675
|
raise ValueError("missing_license_key")
|
|
676
|
+
self._require_app_secret()
|
|
664
677
|
|
|
665
678
|
body = {
|
|
666
679
|
"appId": self.app_id,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: authforge-sdk
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: Official Python SDK for AuthForge — credit-based license key authentication with Ed25519-verified responses.
|
|
5
5
|
Author: AuthForge
|
|
6
6
|
License: MIT
|
|
@@ -110,7 +110,7 @@ client = AuthForgeClient(
|
|
|
110
110
|
| Parameter | Type | Default | Description |
|
|
111
111
|
|---|---|---|---|
|
|
112
112
|
| `app_id` | str | required | Your application ID from the AuthForge dashboard |
|
|
113
|
-
| `app_secret` | str | required | Your application secret from the AuthForge dashboard |
|
|
113
|
+
| `app_secret` | str | required for online APIs; `None` / `""` for `login_from_file` only | Your application secret from the AuthForge dashboard. Do not ship it in air-gapped binaries. |
|
|
114
114
|
| `public_key` | `str \| Sequence[str]` | required | App Ed25519 public key(s) (base64) from dashboard. Pass one key, a list of keys, or a comma-separated string to trust multiple keys during rotation (see [Key rotation](#key-rotation)). |
|
|
115
115
|
| `heartbeat_mode` | `str \| None` | `None` | Deprecated shim (see [Migrating from heartbeat_mode](#migrating-from-heartbeat_mode)). Use `online_heartbeat` instead. |
|
|
116
116
|
| `heartbeat_interval` | int | `900` | Seconds between background checks (minimum `10`; default 15 min). Applies to both grace period checks and online check-ins. |
|
|
@@ -159,7 +159,7 @@ Tune `ttl_seconds` to set the grace period duration (server default 24h, clamped
|
|
|
159
159
|
|
|
160
160
|
## Offline license files (`.authforge`)
|
|
161
161
|
|
|
162
|
-
For machines that never connect to the internet, the operator mints a **signed offline license file** in the AuthForge dashboard (License page -> *Mint .authforge file*) or via `POST /v1/licenses/{licenseKey}/offline-files`. The file is a standalone Ed25519-signed document; the SDK verifies it with **only** your app public key and the machine HWID. It never contacts AuthForge and never starts online check-ins.
|
|
162
|
+
For machines that never connect to the internet, the operator mints a **signed offline license file** in the AuthForge dashboard (License page -> *Mint .authforge file*) or via `POST /v1/licenses/{licenseKey}/offline-files`. The file is a standalone Ed25519-signed document; the SDK verifies it with **only** your app public key and the machine HWID. It never contacts AuthForge and never starts online check-ins. Pass `app_secret=None` (or `""`) so the air-gapped binary does not contain the App Secret.
|
|
163
163
|
|
|
164
164
|
| | Grace period (default) | Offline license file |
|
|
165
165
|
| --- | --- | --- |
|
|
@@ -174,7 +174,7 @@ from authforge import AuthForgeClient
|
|
|
174
174
|
|
|
175
175
|
client = AuthForgeClient(
|
|
176
176
|
app_id="YOUR_APP_ID",
|
|
177
|
-
app_secret=
|
|
177
|
+
app_secret=None, # login_from_file does not use the App Secret; do not ship it in air-gapped builds
|
|
178
178
|
public_key="YOUR_PUBLIC_KEY",
|
|
179
179
|
on_failure=lambda reason, exc: print(reason, exc),
|
|
180
180
|
)
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "authforge-sdk"
|
|
7
|
-
version = "1.2.
|
|
7
|
+
version = "1.2.1"
|
|
8
8
|
description = "Official Python SDK for AuthForge — credit-based license key authentication with Ed25519-verified responses."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|