postex-auth-sdk-stage 1.0.0
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.
- package/README.md +94 -0
- package/dist/auth.d.ts +189 -0
- package/dist/main.d.ts +2 -0
- package/dist/postex-auth-sdk-stage.es.js +632 -0
- package/dist/postex-auth-sdk-stage.es.js.map +1 -0
- package/dist/postex-auth-sdk-stage.iife.js +2 -0
- package/dist/postex-auth-sdk-stage.iife.js.map +1 -0
- package/dist/postex-auth-sdk-stage.umd.js +2 -0
- package/dist/postex-auth-sdk-stage.umd.js.map +1 -0
- package/dist/vite.svg +1 -0
- package/dist/webauthn.d.ts +75 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# PostEx Auth SDK
|
|
2
|
+
|
|
3
|
+
PostEx Auth SDK for authentication flows: OTP, magic links, passkeys (WebAuthn), and token management. Use it in any frontend project via NPM or CDN.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### NPM
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install postex-auth-sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### CDN (jsDelivr)
|
|
14
|
+
|
|
15
|
+
```html
|
|
16
|
+
<script src="https://cdn.jsdelivr.net/npm/postex-auth-sdk@1/dist/postex-auth-sdk.umd.js"></script>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### CDN (unpkg)
|
|
20
|
+
|
|
21
|
+
```html
|
|
22
|
+
<script src="https://unpkg.com/postex-auth-sdk@1/dist/postex-auth-sdk.umd.js"></script>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Use a specific version for production (e.g. `@1.0.0` instead of `@1`).
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### Via CDN (script tag)
|
|
30
|
+
|
|
31
|
+
After loading the script, the SDK is available on the global `PostexAuthSDK` object:
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<script src="https://cdn.jsdelivr.net/npm/postex-auth-sdk@1/dist/postex-auth-sdk.umd.js"></script>
|
|
35
|
+
<script>
|
|
36
|
+
const { AuthSDK, WebAuthn } = PostexAuthSDK;
|
|
37
|
+
const sdk = new AuthSDK({ apiKey: "your-api-key" });
|
|
38
|
+
|
|
39
|
+
// Check auth status
|
|
40
|
+
const status = await sdk.getStatus("user@example.com");
|
|
41
|
+
|
|
42
|
+
// Initiate auth (OTP or WebAuthn)
|
|
43
|
+
const result = await sdk.initiateAuth("user@example.com");
|
|
44
|
+
if (result.status === "webauthn_challenge") {
|
|
45
|
+
const authResult = await sdk.authenticateWithPasskey({
|
|
46
|
+
challenge: result.challenge,
|
|
47
|
+
rp: result.rp,
|
|
48
|
+
credentialIds: result.credentialIds || [],
|
|
49
|
+
});
|
|
50
|
+
} else if (result.status === "otp_sent") {
|
|
51
|
+
const verified = await sdk.verifyOTP("123456");
|
|
52
|
+
}
|
|
53
|
+
</script>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Via NPM (ESM)
|
|
57
|
+
|
|
58
|
+
```javascript
|
|
59
|
+
import { AuthSDK, WebAuthn, AuthSDKFetchError } from "postex-auth-sdk";
|
|
60
|
+
|
|
61
|
+
const sdk = new AuthSDK({ apiKey: "your-api-key" });
|
|
62
|
+
|
|
63
|
+
// Use SDK methods
|
|
64
|
+
const status = await sdk.getStatus("user@example.com");
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### WebAuthn utilities
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
import { WebAuthn } from "postex-auth-sdk";
|
|
71
|
+
|
|
72
|
+
if (WebAuthn.isWebAuthnSupported()) {
|
|
73
|
+
const conditionalUI = await WebAuthn.isConditionalUISupported();
|
|
74
|
+
// ...
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## API overview
|
|
79
|
+
|
|
80
|
+
- **AuthSDK** – Main client: `getStatus`, `initiateAuth`, `verifyOTP`, `verifyMagicLink`, `completeMagicLink`, `authenticateWithPasskey`, `registerPasskey`, `getPasskeyStatus`, `removePasskey`, `getRequestAuthHeaders`, `authenticatedFetch`, `refreshToken`, `logout`, `getAccessToken`, `storeTokens`, `clearTokens`
|
|
81
|
+
- **WebAuthn** – Helpers: `isWebAuthnSupported`, `isConditionalUISupported`, base64/ArrayBuffer conversion, DPoP key and proof helpers, passkey email storage
|
|
82
|
+
- **AuthSDKFetchError** – Error class with `response.status` and `response.data`
|
|
83
|
+
|
|
84
|
+
## Versioning
|
|
85
|
+
|
|
86
|
+
This package follows [semantic versioning](https://semver.org/). CDN URLs support:
|
|
87
|
+
|
|
88
|
+
- `@1` – latest 1.x.x
|
|
89
|
+
- `@1.0` – latest 1.0.x
|
|
90
|
+
- `@1.0.0` – exact version
|
|
91
|
+
|
|
92
|
+
## License
|
|
93
|
+
|
|
94
|
+
MIT
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
interface AuthSDKConfig {
|
|
2
|
+
apiKey?: string;
|
|
3
|
+
}
|
|
4
|
+
type AuthStatusType = "no_session" | "session_found" | "webauthn_ready";
|
|
5
|
+
interface AuthStatusResponse {
|
|
6
|
+
status: AuthStatusType;
|
|
7
|
+
email?: string;
|
|
8
|
+
webauthn?: boolean;
|
|
9
|
+
challenge?: string;
|
|
10
|
+
credentialIds?: string[];
|
|
11
|
+
rp?: {
|
|
12
|
+
name: string;
|
|
13
|
+
host: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/** Response from POST /auth/initiate */
|
|
17
|
+
type InitiateAuthStatusType = "webauthn_challenge" | "otp_sent";
|
|
18
|
+
interface InitiateAuthResponse {
|
|
19
|
+
status: InitiateAuthStatusType;
|
|
20
|
+
challenge?: string;
|
|
21
|
+
credentialIds?: string[];
|
|
22
|
+
rp?: {
|
|
23
|
+
name: string;
|
|
24
|
+
host: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
interface OTPVerifyResponse {
|
|
28
|
+
access_token: string;
|
|
29
|
+
id_token: string;
|
|
30
|
+
refresh_token: string;
|
|
31
|
+
expires_in: number;
|
|
32
|
+
token_type: string;
|
|
33
|
+
verified: boolean;
|
|
34
|
+
email: string;
|
|
35
|
+
[key: string]: any;
|
|
36
|
+
}
|
|
37
|
+
interface PasskeyRegistrationChallenge {
|
|
38
|
+
challenge: string;
|
|
39
|
+
rp: {
|
|
40
|
+
name: string;
|
|
41
|
+
id: string;
|
|
42
|
+
};
|
|
43
|
+
user: {
|
|
44
|
+
id: string;
|
|
45
|
+
name: string;
|
|
46
|
+
displayName: string;
|
|
47
|
+
};
|
|
48
|
+
pubKeyCredParams?: Array<{
|
|
49
|
+
type: string;
|
|
50
|
+
alg: number;
|
|
51
|
+
}>;
|
|
52
|
+
authenticatorSelection?: AuthenticatorSelectionCriteria;
|
|
53
|
+
timeout?: number;
|
|
54
|
+
attestation?: AttestationConveyancePreference;
|
|
55
|
+
/** Existing credential IDs to exclude (prevents duplicate registration) */
|
|
56
|
+
excludeCredentials?: Array<{
|
|
57
|
+
id: string;
|
|
58
|
+
type: "public-key";
|
|
59
|
+
transports?: AuthenticatorTransport[];
|
|
60
|
+
}>;
|
|
61
|
+
}
|
|
62
|
+
interface PasskeyRegisterResponse {
|
|
63
|
+
registered: boolean;
|
|
64
|
+
[key: string]: any;
|
|
65
|
+
}
|
|
66
|
+
interface PasskeyStatusResponse {
|
|
67
|
+
credentialId?: string;
|
|
68
|
+
hasCredentials: boolean;
|
|
69
|
+
[key: string]: any;
|
|
70
|
+
}
|
|
71
|
+
interface AuthResponse {
|
|
72
|
+
access_token: string;
|
|
73
|
+
refresh_token: string;
|
|
74
|
+
id_token?: string;
|
|
75
|
+
email: string;
|
|
76
|
+
name: string;
|
|
77
|
+
expiresIn?: number;
|
|
78
|
+
tokenType?: string;
|
|
79
|
+
[key: string]: any;
|
|
80
|
+
}
|
|
81
|
+
/** Response from POST /auth/refresh */
|
|
82
|
+
interface RefreshTokenResponse {
|
|
83
|
+
access_token: string;
|
|
84
|
+
id_token?: string;
|
|
85
|
+
token_type: string;
|
|
86
|
+
expires_in: number;
|
|
87
|
+
}
|
|
88
|
+
export declare class AuthSDKFetchError extends Error {
|
|
89
|
+
response: {
|
|
90
|
+
status: number;
|
|
91
|
+
data?: any;
|
|
92
|
+
};
|
|
93
|
+
constructor(status: number, data?: any, message?: string);
|
|
94
|
+
}
|
|
95
|
+
export declare class AuthSDK {
|
|
96
|
+
private config;
|
|
97
|
+
constructor(config: AuthSDKConfig);
|
|
98
|
+
private buildUrl;
|
|
99
|
+
private request;
|
|
100
|
+
/**
|
|
101
|
+
* Returns auth headers (Authorization + DPoP) for the given request.
|
|
102
|
+
* Use this to attach auth to your own HTTP client (e.g. axios request interceptor).
|
|
103
|
+
* @param method - HTTP method (e.g. "GET", "POST")
|
|
104
|
+
* @param url - Full request URL
|
|
105
|
+
*/
|
|
106
|
+
getRequestAuthHeaders(method: string, url: string): Promise<Record<string, string>>;
|
|
107
|
+
/**
|
|
108
|
+
* GET /auth/status - Check if client has trusted device session and what auth method is available.
|
|
109
|
+
* Returns no_session | session_found | webauthn_ready per PostEx Auth BFF spec.
|
|
110
|
+
*/
|
|
111
|
+
getStatus(email: string): Promise<AuthStatusResponse>;
|
|
112
|
+
/**
|
|
113
|
+
* POST /auth/initiate - Unified entry: returns webauthn_challenge or otp_sent.
|
|
114
|
+
* Sets auth_session cookie when otp_sent.
|
|
115
|
+
*/
|
|
116
|
+
initiateAuth(email: string): Promise<InitiateAuthResponse>;
|
|
117
|
+
/**
|
|
118
|
+
* POST /otp/verify - Verifies the OTP code entered by the user.
|
|
119
|
+
* Stores tokens from the response.
|
|
120
|
+
*/
|
|
121
|
+
verifyOTP(otp: string): Promise<OTPVerifyResponse>;
|
|
122
|
+
/**
|
|
123
|
+
* GET /magic-link - Verify a magic link token.
|
|
124
|
+
* Sets auth_session cookie on success.
|
|
125
|
+
*/
|
|
126
|
+
verifyMagicLink(token: string, email: string): Promise<void>;
|
|
127
|
+
/**
|
|
128
|
+
* POST /magic-link/complete - Complete magic link authentication.
|
|
129
|
+
* Requires auth_session cookie set by verifyMagicLink.
|
|
130
|
+
* Stores tokens from the response.
|
|
131
|
+
*/
|
|
132
|
+
completeMagicLink(): Promise<OTPVerifyResponse>;
|
|
133
|
+
initiatePasskeyRegistration(): Promise<PasskeyRegistrationChallenge>;
|
|
134
|
+
registerPasskey(email: string): Promise<PasskeyRegisterResponse>;
|
|
135
|
+
/**
|
|
136
|
+
* POST /webauthn/authenticate/challenge - Authenticate with passkey.
|
|
137
|
+
*/
|
|
138
|
+
authenticateWithPasskey({ challenge, rp, credentialIds, }: {
|
|
139
|
+
challenge: string;
|
|
140
|
+
rp: {
|
|
141
|
+
name: string;
|
|
142
|
+
host: string;
|
|
143
|
+
};
|
|
144
|
+
credentialIds: string[];
|
|
145
|
+
}): Promise<AuthResponse>;
|
|
146
|
+
/**
|
|
147
|
+
* GET /webauthn/credentials/:username - Get user's passkey status.
|
|
148
|
+
*/
|
|
149
|
+
getPasskeyStatus(username: string): Promise<PasskeyStatusResponse>;
|
|
150
|
+
/**
|
|
151
|
+
* DELETE /webauthn/credentials/:username - Remove passkey.
|
|
152
|
+
*/
|
|
153
|
+
removePasskey(username: string): Promise<void>;
|
|
154
|
+
/**
|
|
155
|
+
* Signs a request with DPoP and Authorization headers (internal use).
|
|
156
|
+
*/
|
|
157
|
+
signRequest(method: string, url: string, config?: any): Promise<any>;
|
|
158
|
+
/**
|
|
159
|
+
* Replaces native fetch or Axios with a DPoP-signed version.
|
|
160
|
+
*/
|
|
161
|
+
authenticatedFetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
162
|
+
/**
|
|
163
|
+
* Store tokens from /webauthn/authenticate (per spec: sessionStorage preferred).
|
|
164
|
+
*/
|
|
165
|
+
storeTokens(tokens: {
|
|
166
|
+
accessToken: string;
|
|
167
|
+
refreshToken?: string;
|
|
168
|
+
idToken?: string;
|
|
169
|
+
expiresIn?: number;
|
|
170
|
+
tokenType?: string;
|
|
171
|
+
}): Promise<void>;
|
|
172
|
+
/**
|
|
173
|
+
* Clear stored tokens (call on logout).
|
|
174
|
+
*/
|
|
175
|
+
clearTokens(): Promise<void>;
|
|
176
|
+
/**
|
|
177
|
+
* POST /auth/refresh - Refresh access token using server-stored refresh token.
|
|
178
|
+
* Requires trusted device cookie (td). Refresh token is stored server-side.
|
|
179
|
+
* Rate limit: 10 requests per minute.
|
|
180
|
+
*/
|
|
181
|
+
refreshToken(): Promise<RefreshTokenResponse>;
|
|
182
|
+
/**
|
|
183
|
+
* POST /auth/logout - Logout from the current device.
|
|
184
|
+
* Revokes the current token and trusted device, then clears local tokens.
|
|
185
|
+
*/
|
|
186
|
+
logout(): Promise<void>;
|
|
187
|
+
getAccessToken(): Promise<string | null>;
|
|
188
|
+
}
|
|
189
|
+
export {};
|
package/dist/main.d.ts
ADDED