@softwarepatterns/am 0.0.1
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 +215 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +205 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -0
- package/dist/types/auth.d.ts +134 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/types.d.ts +77 -0
- package/package.json +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# `@softwarepatterns/am`
|
|
2
|
+
|
|
3
|
+
Authentication client SDK for **AccountMaker (Am)**.
|
|
4
|
+
|
|
5
|
+
This package provides a small, stable client for interacting with the AccountMaker authentication API. It is designed for **Node.js applications** and **modern bundlers**, with explicit support for both **ESM** and **CommonJS** consumers.
|
|
6
|
+
|
|
7
|
+
The SDK focuses on correctness, predictable behavior, and minimal surface area.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
* ESM and CommonJS support
|
|
14
|
+
* TypeScript-first API with bundled `.d.ts`
|
|
15
|
+
* Explicit error modeling using Problem Details
|
|
16
|
+
* Token-based authenticated sessions
|
|
17
|
+
* Automatic access-token refresh
|
|
18
|
+
* No runtime dependencies
|
|
19
|
+
* No side effects on import
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Requirements
|
|
24
|
+
|
|
25
|
+
* **Node.js ≥ 18**
|
|
26
|
+
* A runtime with a global `fetch` implementation
|
|
27
|
+
(Node 18+, Bun, Deno, or a custom `fetchFn`)
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install @softwarepatterns/am
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Importing
|
|
40
|
+
|
|
41
|
+
### ESM
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import { Am } from "@softwarepatterns/am";
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### CommonJS
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
const { Am } = require("@softwarepatterns/am");
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Basic usage
|
|
56
|
+
|
|
57
|
+
### Create a client
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import { Am } from "@softwarepatterns/am";
|
|
61
|
+
|
|
62
|
+
const am = new Am({
|
|
63
|
+
baseUrl: "https://api.accountmaker.com"
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
If no configuration is provided, the client defaults to:
|
|
68
|
+
|
|
69
|
+
* `baseUrl: https://api.accountmaker.com`
|
|
70
|
+
* `fetchFn: globalThis.fetch`
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Authentication flows
|
|
75
|
+
|
|
76
|
+
### Login with email and password
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
const result = await am.login({
|
|
80
|
+
email: "user@example.com",
|
|
81
|
+
password: "password"
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The result contains both session tokens and the authenticated profile.
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
result.session;
|
|
89
|
+
result.profile;
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
### Create an authenticated session
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
const session = am.createAuthSession(result.session);
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
An `AuthSession` represents an authenticated user and handles token refresh automatically.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
### Fetch the current user
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
const me = await session.me();
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
### Refresh tokens explicitly
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
await session.refresh();
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Error handling
|
|
121
|
+
|
|
122
|
+
All API errors are surfaced as `AuthError`.
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import { AuthError } from "@softwarepatterns/am";
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
await am.login({ email, password });
|
|
129
|
+
} catch (err) {
|
|
130
|
+
if (err instanceof AuthError) {
|
|
131
|
+
console.log(err.status);
|
|
132
|
+
console.log(err.title);
|
|
133
|
+
console.log(err.detail);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Errors follow the **Problem Details** format (`application/problem+json`).
|
|
139
|
+
|
|
140
|
+
Unknown or unsupported error responses are converted into a generic problem shape without exposing raw response bodies.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Custom fetch implementation
|
|
145
|
+
|
|
146
|
+
If the runtime does not provide a global `fetch`, supply one explicitly.
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
const am = new Am({
|
|
150
|
+
fetchFn: fetch,
|
|
151
|
+
baseUrl: "https://api.accountmaker.com"
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
This is useful for:
|
|
156
|
+
|
|
157
|
+
* Older Node versions
|
|
158
|
+
* Instrumented HTTP clients
|
|
159
|
+
* Testing
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## TypeScript support
|
|
164
|
+
|
|
165
|
+
This package ships with bundled type definitions.
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import type { AuthenticationResult } from "@softwarepatterns/am";
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
The public API is fully typed. Internal implementation details are not exposed.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Browser support
|
|
176
|
+
|
|
177
|
+
This SDK does **not currently claim browser runtime support**.
|
|
178
|
+
|
|
179
|
+
However:
|
|
180
|
+
|
|
181
|
+
* The package is free of Node-only runtime APIs
|
|
182
|
+
* It can be bundled by modern tools (Vite, Rollup, Webpack)
|
|
183
|
+
|
|
184
|
+
Browser runtime support may be added in a future release, along with explicit guarantees and tests.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Stability guarantees
|
|
189
|
+
|
|
190
|
+
The following are guaranteed:
|
|
191
|
+
|
|
192
|
+
* Stable ESM and CommonJS entry points
|
|
193
|
+
* Stable TypeScript types for exported symbols
|
|
194
|
+
* Compatibility with Node 18, 20, and 22
|
|
195
|
+
* Deterministic build and publish artifacts
|
|
196
|
+
|
|
197
|
+
The following are **not** guaranteed yet:
|
|
198
|
+
|
|
199
|
+
* Browser runtime behavior
|
|
200
|
+
* Backward compatibility prior to `1.0.0`
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Versioning
|
|
205
|
+
|
|
206
|
+
This package follows semantic versioning.
|
|
207
|
+
|
|
208
|
+
* `0.x` releases may introduce breaking changes
|
|
209
|
+
* `1.0.0` will mark a frozen public API
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## License
|
|
214
|
+
|
|
215
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";function t(t){return t.replace(/_([a-z])/g,(t,e)=>e.toUpperCase())}function e(n){if(null===n||"object"!=typeof n)return n;if(Array.isArray(n))return n.map(t=>e(t));const s=n,r={};for(const n of Object.keys(s))Object.prototype.hasOwnProperty.call(s,n)&&(r[t(n)]=e(s[n]));return r}function n(t){return t.replace(/[A-Z]/g,t=>`_${t.toLowerCase()}`)}function s(t){if(null===t||"object"!=typeof t)return t;if(Array.isArray(t))return t.map(t=>s(t));const e=t,r={};for(const t of Object.keys(e))Object.prototype.hasOwnProperty.call(e,t)&&(r[n(t)]=s(e[t]));return r}class r extends Error{constructor(t){super(t.title),this.name="AuthError",this.problem=Object.freeze(t)}get type(){return this.problem.type}get title(){return this.problem.title}get status(){return this.problem.status}get code(){return this.problem.code}get detail(){return this.problem.detail}get invalidParams(){return this.problem.invalidParams}}const a={fetchFn:function(){const t=globalThis.fetch;return"function"==typeof t?t:async()=>{throw new Error("Missing fetch implementation. Provide config.fetchFn or use a runtime with global fetch.")}}(),baseUrl:"https://api.accountmaker.com"};const i=async t=>{if(204===t.status)return;const n=await async function(t){const e=t.headers.get("Content-Type")||"";if(!e.includes("application/json")&&!e.includes("+json"))return null;try{return await t.json()}catch{return null}}(t),s=e(n);if(!t.ok){if(function(t){return(t.headers.get("Content-Type")||"").includes("application/problem+json")}(t)&&s&&"object"==typeof s)throw new r(s);throw new r(function(t,e){return{type:"about:blank",title:t.statusText||"Request failed",status:t.status,detail:e}}(t,"string"==typeof n?n:void 0))}return s},o=async({fetchFn:t,baseUrl:e},n,r={})=>{const a=new URLSearchParams(s(r)).toString(),o=a?`${e}${n}?${a}`:`${e}${n}`,c=await t(o,{method:"GET",headers:{Accept:"application/json"}});return i(c)},c=async({fetchFn:t,baseUrl:e},n,r)=>{const a=await t(`${e}${n}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s(r))});return i(a)},h=async({accessToken:t},{fetchFn:e,baseUrl:n},r,a={})=>{const o=new URLSearchParams(s(a)).toString(),c=o?`${n}${r}?${o}`:`${n}${r}`,h=await e(c,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t}`}});return i(h)};class u{constructor(t,e){this.tokens=t,this.config={...a,...e},this.lastUpdated=new Date}get accessToken(){return this.tokens.accessToken}get refreshToken(){return this.tokens.refreshToken}get idToken(){return this.tokens.idToken}get tokenType(){return this.tokens.tokenType}get expiresIn(){return this.tokens.expiresIn}get lastUpdatedAt(){return this.lastUpdated}get expiresAt(){return new Date(this.lastUpdated.getTime()+1e3*this.expiresIn)}isExpired(){return Date.now()>=this.expiresAt.getTime()-6e4}async fetch(t,e={}){const{fetchFn:n}=this.config;return this.isExpired()&&await this.refresh(),await n(t,{...e,headers:{...e.headers||{},Authorization:`Bearer ${this.tokens.accessToken}`}})}async refresh(){const{fetchFn:t,baseUrl:e}=this.config,n=await t(`${e}/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s({refreshToken:this.tokens.refreshToken}))}),r=await i(n);this.tokens=r,this.lastUpdated=new Date}async sendVerificationEmail(){await(async({accessToken:t},{fetchFn:e,baseUrl:n},r,a)=>{const o=await e(`${n}${r}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(s(a))});return i(o)})(this,this.config,"/auth/send-verification-email",{})}async me(){return await h(this,this.config,"/auth/me",{})}async user(t){return await h(this,this.config,`/auth/user/${t}`,{})}}class p{constructor(t){this.options={...a,...t}}static createAuthSession(t,e){return new p(e).createAuthSession(t)}createAuthSession(t){return new u(t,this.options)}static async acceptInvite(t,e){return new p(e).acceptInvite(t)}async acceptInvite(t){return await o(this.options,"/auth/accept-invite",t)}static async checkEmail(t,e){return new p(e).checkEmail(t)}async checkEmail(t){return c(this.options,"/auth/check-email",t)}static async csrfSession(t){return new p(t).csrfSession()}async csrfSession(){return o(this.options,"/auth/csrf-session")}static async csrfToken(t){return new p(t).csrfToken()}async csrfToken(){return o(this.options,"/auth/csrf-token")}static async login(t,e){return new p(e).login(t)}async login(t){return await c(this.options,"/auth/login",t)}static async tokenLogin(t,e){return new p(e).tokenLogin(t)}async tokenLogin(t){const e=this.options;return await o(e,"/auth/token-login",{token:t})}static async refresh(t,e){return new p(e).refresh(t)}async refresh(t){return await c(this.options,"/auth/refresh",{refreshToken:t})}static async register(t,e){return new p(e).register(t)}async register(t){return await c(this.options,"/auth/register",t)}static async resetPassword(t,e){return new p(e).resetPassword(t)}async resetPassword(t){return c(this.options,"/auth/reset-password",t)}static async sendMagicLink(t,e){return new p(e).sendMagicLink(t)}async sendMagicLink(t){return c(this.options,"/auth/send-magic-link",t)}static async sendPasswordReset(t,e){return new p(e).sendPasswordReset(t)}async sendPasswordReset(t){return c(this.options,"/auth/send-password-reset",t)}}exports.Am=p,exports.AuthError=r,exports.AuthSession=u;
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/auth.ts"],"sourcesContent":[null],"names":["camelCaseStr","str","replace","_","letter","toUpperCase","camelCaseObj","input","Array","isArray","map","item","obj","result","key","Object","keys","prototype","hasOwnProperty","call","snakeCaseStr","toLowerCase","snakeCaseObj","AuthError","Error","constructor","problem","super","title","this","name","freeze","type","status","code","detail","invalidParams","defaultConfig","fetchFn","f","globalThis","fetch","async","defaultFetchFn","baseUrl","handleResponse","res","raw","contentType","headers","get","includes","json","readJsonSafe","ok","isProblemJson","statusText","toGenericProblem","undefined","unauthGet","path","query","qs","URLSearchParams","toString","url","method","Accept","unauthPost","body","JSON","stringify","authGet","accessToken","Authorization","AuthSession","tokens","config","lastUpdated","Date","refreshToken","idToken","tokenType","expiresIn","lastUpdatedAt","expiresAt","getTime","isExpired","now","init","refresh","sendVerificationEmail","authPost","me","user","id","Am","options","createAuthSession","acceptInvite","checkEmail","csrfSession","csrfToken","login","tokenLogin","token","register","resetPassword","sendMagicLink","sendPasswordReset"],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
type ProblemDetails = {
|
|
2
|
+
type: string;
|
|
3
|
+
title: string;
|
|
4
|
+
status: number;
|
|
5
|
+
code?: string;
|
|
6
|
+
detail?: string;
|
|
7
|
+
invalidParams?: {
|
|
8
|
+
in: "body" | "cookie" | "header" | "query" | "path";
|
|
9
|
+
path: string;
|
|
10
|
+
type: string;
|
|
11
|
+
received: unknown;
|
|
12
|
+
expected?: string;
|
|
13
|
+
}[];
|
|
14
|
+
};
|
|
15
|
+
type ClientId = `cid${string}`;
|
|
16
|
+
type UserId = `uid${string}`;
|
|
17
|
+
type AccountId = `acc${string}`;
|
|
18
|
+
type MembershipId = `mbr${string}`;
|
|
19
|
+
type UserStatus = "active" | "trial" | "past_due" | "suspended" | "closed";
|
|
20
|
+
type UserResource = {
|
|
21
|
+
id: UserId;
|
|
22
|
+
accountId: AccountId;
|
|
23
|
+
status: UserStatus;
|
|
24
|
+
preferredMembershipId: MembershipId | null;
|
|
25
|
+
};
|
|
26
|
+
type UserIdentity = {
|
|
27
|
+
id: UserId;
|
|
28
|
+
avatarUrl: string | null;
|
|
29
|
+
externalId: string | null;
|
|
30
|
+
givenName: string | null;
|
|
31
|
+
familyName: string | null;
|
|
32
|
+
displayName: string | null;
|
|
33
|
+
preferredLanguage: string | null;
|
|
34
|
+
locale: string | null;
|
|
35
|
+
timezone: string | null;
|
|
36
|
+
};
|
|
37
|
+
type MembershipRole = "owner" | "member" | "viewer";
|
|
38
|
+
type Membership = {
|
|
39
|
+
id: MembershipId;
|
|
40
|
+
userId: UserId;
|
|
41
|
+
accountId: AccountId;
|
|
42
|
+
role: MembershipRole;
|
|
43
|
+
};
|
|
44
|
+
type EmailCredential = {
|
|
45
|
+
id: string;
|
|
46
|
+
email: string | null;
|
|
47
|
+
hashedEmail: string | null;
|
|
48
|
+
hashedPassword: string | null;
|
|
49
|
+
emailVerifiedAt: string | null;
|
|
50
|
+
};
|
|
51
|
+
type SessionTokens = {
|
|
52
|
+
accessToken: string;
|
|
53
|
+
refreshToken: string;
|
|
54
|
+
tokenType: "Bearer";
|
|
55
|
+
expiresIn: number;
|
|
56
|
+
idToken?: string;
|
|
57
|
+
};
|
|
58
|
+
type SessionProfile = UserResource & {
|
|
59
|
+
identity: UserIdentity;
|
|
60
|
+
emailCredentials: EmailCredential[];
|
|
61
|
+
memberships: Membership[];
|
|
62
|
+
activeMembership: Membership | null;
|
|
63
|
+
};
|
|
64
|
+
type AuthenticationResult = {
|
|
65
|
+
session: SessionTokens;
|
|
66
|
+
profile: SessionProfile;
|
|
67
|
+
};
|
|
68
|
+
type EmailCheckStatus = "active" | "inactive";
|
|
69
|
+
type LoginMethod = "email_password" | "magic_link";
|
|
70
|
+
|
|
71
|
+
type FetchFn = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
72
|
+
declare class AuthError extends Error {
|
|
73
|
+
readonly problem: ProblemDetails;
|
|
74
|
+
constructor(problem: ProblemDetails);
|
|
75
|
+
get type(): string;
|
|
76
|
+
get title(): string;
|
|
77
|
+
get status(): number;
|
|
78
|
+
get code(): string | undefined;
|
|
79
|
+
get detail(): string | undefined;
|
|
80
|
+
get invalidParams(): ProblemDetails["invalidParams"] | undefined;
|
|
81
|
+
}
|
|
82
|
+
type Config = {
|
|
83
|
+
fetchFn: FetchFn;
|
|
84
|
+
baseUrl: string;
|
|
85
|
+
};
|
|
86
|
+
declare class AuthSession {
|
|
87
|
+
private tokens;
|
|
88
|
+
private config;
|
|
89
|
+
private lastUpdated;
|
|
90
|
+
constructor(tokens: SessionTokens, config: Partial<Config>);
|
|
91
|
+
get accessToken(): string;
|
|
92
|
+
get refreshToken(): string;
|
|
93
|
+
get idToken(): string | undefined;
|
|
94
|
+
get tokenType(): "Bearer";
|
|
95
|
+
get expiresIn(): number;
|
|
96
|
+
get lastUpdatedAt(): Date;
|
|
97
|
+
get expiresAt(): Date;
|
|
98
|
+
isExpired(): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Fetch with automatic token refresh.
|
|
101
|
+
*
|
|
102
|
+
* If the access token is expired, it will be refreshed before making the request. The
|
|
103
|
+
* Authorization header will be set with the current access token.
|
|
104
|
+
*/
|
|
105
|
+
fetch(url: string | URL | Request, init?: RequestInit): Promise<Response>;
|
|
106
|
+
refresh(): Promise<void>;
|
|
107
|
+
sendVerificationEmail(): Promise<void>;
|
|
108
|
+
me(): Promise<SessionProfile>;
|
|
109
|
+
user(id: UserId): Promise<UserResource>;
|
|
110
|
+
}
|
|
111
|
+
declare class Am {
|
|
112
|
+
private options;
|
|
113
|
+
constructor(config?: Partial<Config>);
|
|
114
|
+
static createAuthSession(tokens: SessionTokens, config?: Partial<Config>): AuthSession;
|
|
115
|
+
createAuthSession(tokens: SessionTokens): AuthSession;
|
|
116
|
+
static acceptInvite(query: {
|
|
117
|
+
clientId: ClientId;
|
|
118
|
+
token: string;
|
|
119
|
+
}, config?: Partial<Config>): Promise<AuthenticationResult>;
|
|
120
|
+
acceptInvite(query: {
|
|
121
|
+
clientId: ClientId;
|
|
122
|
+
token: string;
|
|
123
|
+
}): Promise<AuthenticationResult>;
|
|
124
|
+
static checkEmail(body: {
|
|
125
|
+
clientId: ClientId;
|
|
126
|
+
email: string;
|
|
127
|
+
csrfToken?: string;
|
|
128
|
+
}, config?: Partial<Config>): Promise<{
|
|
129
|
+
status: EmailCheckStatus;
|
|
130
|
+
preferred: LoginMethod[];
|
|
131
|
+
available: LoginMethod[];
|
|
132
|
+
}>;
|
|
133
|
+
checkEmail(body: {
|
|
134
|
+
clientId: ClientId;
|
|
135
|
+
email: string;
|
|
136
|
+
csrfToken?: string;
|
|
137
|
+
}): Promise<{
|
|
138
|
+
status: EmailCheckStatus;
|
|
139
|
+
preferred: LoginMethod[];
|
|
140
|
+
available: LoginMethod[];
|
|
141
|
+
}>;
|
|
142
|
+
static csrfSession(config?: Partial<Config>): Promise<{
|
|
143
|
+
csrfToken: string;
|
|
144
|
+
}>;
|
|
145
|
+
csrfSession(): Promise<{
|
|
146
|
+
csrfToken: string;
|
|
147
|
+
}>;
|
|
148
|
+
static csrfToken(config?: Partial<Config>): Promise<{
|
|
149
|
+
csrfToken: string;
|
|
150
|
+
}>;
|
|
151
|
+
csrfToken(): Promise<{
|
|
152
|
+
csrfToken: string;
|
|
153
|
+
}>;
|
|
154
|
+
static login(body: {
|
|
155
|
+
email: string;
|
|
156
|
+
password: string;
|
|
157
|
+
csrfToken?: string;
|
|
158
|
+
}, config?: Partial<Config>): Promise<AuthenticationResult>;
|
|
159
|
+
login(body: {
|
|
160
|
+
email: string;
|
|
161
|
+
password: string;
|
|
162
|
+
csrfToken?: string;
|
|
163
|
+
}): Promise<AuthenticationResult>;
|
|
164
|
+
static tokenLogin(token: string, config?: Partial<Config>): Promise<AuthenticationResult>;
|
|
165
|
+
tokenLogin(token: string): Promise<AuthenticationResult>;
|
|
166
|
+
static refresh(refreshToken: string, config?: Partial<Config>): Promise<SessionTokens>;
|
|
167
|
+
refresh(refreshToken: string): Promise<SessionTokens>;
|
|
168
|
+
static register(body: {
|
|
169
|
+
email: string;
|
|
170
|
+
password: string;
|
|
171
|
+
csrfToken?: string;
|
|
172
|
+
}, config?: Partial<Config>): Promise<AuthenticationResult>;
|
|
173
|
+
register(body: {
|
|
174
|
+
email: string;
|
|
175
|
+
password: string;
|
|
176
|
+
csrfToken?: string;
|
|
177
|
+
}): Promise<AuthenticationResult>;
|
|
178
|
+
static resetPassword(body: {
|
|
179
|
+
token: string;
|
|
180
|
+
newPassword: string;
|
|
181
|
+
}, config?: Partial<Config>): Promise<void>;
|
|
182
|
+
resetPassword(body: {
|
|
183
|
+
token: string;
|
|
184
|
+
newPassword: string;
|
|
185
|
+
}): Promise<void>;
|
|
186
|
+
static sendMagicLink(body: {
|
|
187
|
+
email: string;
|
|
188
|
+
csrfToken?: string;
|
|
189
|
+
}, config?: Partial<Config>): Promise<void>;
|
|
190
|
+
sendMagicLink(body: {
|
|
191
|
+
email: string;
|
|
192
|
+
csrfToken?: string;
|
|
193
|
+
}): Promise<void>;
|
|
194
|
+
static sendPasswordReset(body: {
|
|
195
|
+
email: string;
|
|
196
|
+
csrfToken?: string;
|
|
197
|
+
}, config?: Partial<Config>): Promise<void>;
|
|
198
|
+
sendPasswordReset(body: {
|
|
199
|
+
email: string;
|
|
200
|
+
csrfToken?: string;
|
|
201
|
+
}): Promise<void>;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export { Am, AuthError, AuthSession };
|
|
205
|
+
export type { AuthenticationResult, ClientId, EmailCheckStatus, LoginMethod, ProblemDetails, SessionProfile, SessionTokens, UserId, UserResource };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function t(t){return t.replace(/_([a-z])/g,(t,e)=>e.toUpperCase())}function e(n){if(null===n||"object"!=typeof n)return n;if(Array.isArray(n))return n.map(t=>e(t));const s=n,r={};for(const n of Object.keys(s))Object.prototype.hasOwnProperty.call(s,n)&&(r[t(n)]=e(s[n]));return r}function n(t){return t.replace(/[A-Z]/g,t=>`_${t.toLowerCase()}`)}function s(t){if(null===t||"object"!=typeof t)return t;if(Array.isArray(t))return t.map(t=>s(t));const e=t,r={};for(const t of Object.keys(e))Object.prototype.hasOwnProperty.call(e,t)&&(r[n(t)]=s(e[t]));return r}class r extends Error{constructor(t){super(t.title),this.name="AuthError",this.problem=Object.freeze(t)}get type(){return this.problem.type}get title(){return this.problem.title}get status(){return this.problem.status}get code(){return this.problem.code}get detail(){return this.problem.detail}get invalidParams(){return this.problem.invalidParams}}const a={fetchFn:function(){const t=globalThis.fetch;return"function"==typeof t?t:async()=>{throw new Error("Missing fetch implementation. Provide config.fetchFn or use a runtime with global fetch.")}}(),baseUrl:"https://api.accountmaker.com"};const i=async t=>{if(204===t.status)return;const n=await async function(t){const e=t.headers.get("Content-Type")||"";if(!e.includes("application/json")&&!e.includes("+json"))return null;try{return await t.json()}catch{return null}}(t),s=e(n);if(!t.ok){if(function(t){return(t.headers.get("Content-Type")||"").includes("application/problem+json")}(t)&&s&&"object"==typeof s)throw new r(s);throw new r(function(t,e){return{type:"about:blank",title:t.statusText||"Request failed",status:t.status,detail:e}}(t,"string"==typeof n?n:void 0))}return s},o=async({fetchFn:t,baseUrl:e},n,r={})=>{const a=new URLSearchParams(s(r)).toString(),o=a?`${e}${n}?${a}`:`${e}${n}`,c=await t(o,{method:"GET",headers:{Accept:"application/json"}});return i(c)},c=async({fetchFn:t,baseUrl:e},n,r)=>{const a=await t(`${e}${n}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s(r))});return i(a)},h=async({accessToken:t},{fetchFn:e,baseUrl:n},r,a={})=>{const o=new URLSearchParams(s(a)).toString(),c=o?`${n}${r}?${o}`:`${n}${r}`,h=await e(c,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t}`}});return i(h)};class u{constructor(t,e){this.tokens=t,this.config={...a,...e},this.lastUpdated=new Date}get accessToken(){return this.tokens.accessToken}get refreshToken(){return this.tokens.refreshToken}get idToken(){return this.tokens.idToken}get tokenType(){return this.tokens.tokenType}get expiresIn(){return this.tokens.expiresIn}get lastUpdatedAt(){return this.lastUpdated}get expiresAt(){return new Date(this.lastUpdated.getTime()+1e3*this.expiresIn)}isExpired(){return Date.now()>=this.expiresAt.getTime()-6e4}async fetch(t,e={}){const{fetchFn:n}=this.config;return this.isExpired()&&await this.refresh(),await n(t,{...e,headers:{...e.headers||{},Authorization:`Bearer ${this.tokens.accessToken}`}})}async refresh(){const{fetchFn:t,baseUrl:e}=this.config,n=await t(`${e}/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s({refreshToken:this.tokens.refreshToken}))}),r=await i(n);this.tokens=r,this.lastUpdated=new Date}async sendVerificationEmail(){await(async({accessToken:t},{fetchFn:e,baseUrl:n},r,a)=>{const o=await e(`${n}${r}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(s(a))});return i(o)})(this,this.config,"/auth/send-verification-email",{})}async me(){return await h(this,this.config,"/auth/me",{})}async user(t){return await h(this,this.config,`/auth/user/${t}`,{})}}class p{constructor(t){this.options={...a,...t}}static createAuthSession(t,e){return new p(e).createAuthSession(t)}createAuthSession(t){return new u(t,this.options)}static async acceptInvite(t,e){return new p(e).acceptInvite(t)}async acceptInvite(t){return await o(this.options,"/auth/accept-invite",t)}static async checkEmail(t,e){return new p(e).checkEmail(t)}async checkEmail(t){return c(this.options,"/auth/check-email",t)}static async csrfSession(t){return new p(t).csrfSession()}async csrfSession(){return o(this.options,"/auth/csrf-session")}static async csrfToken(t){return new p(t).csrfToken()}async csrfToken(){return o(this.options,"/auth/csrf-token")}static async login(t,e){return new p(e).login(t)}async login(t){return await c(this.options,"/auth/login",t)}static async tokenLogin(t,e){return new p(e).tokenLogin(t)}async tokenLogin(t){const e=this.options;return await o(e,"/auth/token-login",{token:t})}static async refresh(t,e){return new p(e).refresh(t)}async refresh(t){return await c(this.options,"/auth/refresh",{refreshToken:t})}static async register(t,e){return new p(e).register(t)}async register(t){return await c(this.options,"/auth/register",t)}static async resetPassword(t,e){return new p(e).resetPassword(t)}async resetPassword(t){return c(this.options,"/auth/reset-password",t)}static async sendMagicLink(t,e){return new p(e).sendMagicLink(t)}async sendMagicLink(t){return c(this.options,"/auth/send-magic-link",t)}static async sendPasswordReset(t,e){return new p(e).sendPasswordReset(t)}async sendPasswordReset(t){return c(this.options,"/auth/send-password-reset",t)}}export{p as Am,r as AuthError,u as AuthSession};
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/auth.ts"],"sourcesContent":[null],"names":["camelCaseStr","str","replace","_","letter","toUpperCase","camelCaseObj","input","Array","isArray","map","item","obj","result","key","Object","keys","prototype","hasOwnProperty","call","snakeCaseStr","toLowerCase","snakeCaseObj","AuthError","Error","constructor","problem","super","title","this","name","freeze","type","status","code","detail","invalidParams","defaultConfig","fetchFn","f","globalThis","fetch","async","defaultFetchFn","baseUrl","handleResponse","res","raw","contentType","headers","get","includes","json","readJsonSafe","ok","isProblemJson","statusText","toGenericProblem","undefined","unauthGet","path","query","qs","URLSearchParams","toString","url","method","Accept","unauthPost","body","JSON","stringify","authGet","accessToken","Authorization","AuthSession","tokens","config","lastUpdated","Date","refreshToken","idToken","tokenType","expiresIn","lastUpdatedAt","expiresAt","getTime","isExpired","now","init","refresh","sendVerificationEmail","authPost","me","user","id","Am","options","createAuthSession","acceptInvite","checkEmail","csrfSession","csrfToken","login","tokenLogin","token","register","resetPassword","sendMagicLink","sendPasswordReset"],"mappings":"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"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { AuthenticationResult, ClientId, EmailCheckStatus, LoginMethod, ProblemDetails, SessionProfile, SessionTokens, UserId, UserResource } from "./types";
|
|
2
|
+
type FetchFn = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
3
|
+
export declare class AuthError extends Error {
|
|
4
|
+
readonly problem: ProblemDetails;
|
|
5
|
+
constructor(problem: ProblemDetails);
|
|
6
|
+
get type(): string;
|
|
7
|
+
get title(): string;
|
|
8
|
+
get status(): number;
|
|
9
|
+
get code(): string | undefined;
|
|
10
|
+
get detail(): string | undefined;
|
|
11
|
+
get invalidParams(): ProblemDetails["invalidParams"] | undefined;
|
|
12
|
+
}
|
|
13
|
+
type Config = {
|
|
14
|
+
fetchFn: FetchFn;
|
|
15
|
+
baseUrl: string;
|
|
16
|
+
};
|
|
17
|
+
export declare class AuthSession {
|
|
18
|
+
private tokens;
|
|
19
|
+
private config;
|
|
20
|
+
private lastUpdated;
|
|
21
|
+
constructor(tokens: SessionTokens, config: Partial<Config>);
|
|
22
|
+
get accessToken(): string;
|
|
23
|
+
get refreshToken(): string;
|
|
24
|
+
get idToken(): string | undefined;
|
|
25
|
+
get tokenType(): "Bearer";
|
|
26
|
+
get expiresIn(): number;
|
|
27
|
+
get lastUpdatedAt(): Date;
|
|
28
|
+
get expiresAt(): Date;
|
|
29
|
+
isExpired(): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Fetch with automatic token refresh.
|
|
32
|
+
*
|
|
33
|
+
* If the access token is expired, it will be refreshed before making the request. The
|
|
34
|
+
* Authorization header will be set with the current access token.
|
|
35
|
+
*/
|
|
36
|
+
fetch(url: string | URL | Request, init?: RequestInit): Promise<Response>;
|
|
37
|
+
refresh(): Promise<void>;
|
|
38
|
+
sendVerificationEmail(): Promise<void>;
|
|
39
|
+
me(): Promise<SessionProfile>;
|
|
40
|
+
user(id: UserId): Promise<UserResource>;
|
|
41
|
+
}
|
|
42
|
+
export declare class Am {
|
|
43
|
+
private options;
|
|
44
|
+
constructor(config?: Partial<Config>);
|
|
45
|
+
static createAuthSession(tokens: SessionTokens, config?: Partial<Config>): AuthSession;
|
|
46
|
+
createAuthSession(tokens: SessionTokens): AuthSession;
|
|
47
|
+
static acceptInvite(query: {
|
|
48
|
+
clientId: ClientId;
|
|
49
|
+
token: string;
|
|
50
|
+
}, config?: Partial<Config>): Promise<AuthenticationResult>;
|
|
51
|
+
acceptInvite(query: {
|
|
52
|
+
clientId: ClientId;
|
|
53
|
+
token: string;
|
|
54
|
+
}): Promise<AuthenticationResult>;
|
|
55
|
+
static checkEmail(body: {
|
|
56
|
+
clientId: ClientId;
|
|
57
|
+
email: string;
|
|
58
|
+
csrfToken?: string;
|
|
59
|
+
}, config?: Partial<Config>): Promise<{
|
|
60
|
+
status: EmailCheckStatus;
|
|
61
|
+
preferred: LoginMethod[];
|
|
62
|
+
available: LoginMethod[];
|
|
63
|
+
}>;
|
|
64
|
+
checkEmail(body: {
|
|
65
|
+
clientId: ClientId;
|
|
66
|
+
email: string;
|
|
67
|
+
csrfToken?: string;
|
|
68
|
+
}): Promise<{
|
|
69
|
+
status: EmailCheckStatus;
|
|
70
|
+
preferred: LoginMethod[];
|
|
71
|
+
available: LoginMethod[];
|
|
72
|
+
}>;
|
|
73
|
+
static csrfSession(config?: Partial<Config>): Promise<{
|
|
74
|
+
csrfToken: string;
|
|
75
|
+
}>;
|
|
76
|
+
csrfSession(): Promise<{
|
|
77
|
+
csrfToken: string;
|
|
78
|
+
}>;
|
|
79
|
+
static csrfToken(config?: Partial<Config>): Promise<{
|
|
80
|
+
csrfToken: string;
|
|
81
|
+
}>;
|
|
82
|
+
csrfToken(): Promise<{
|
|
83
|
+
csrfToken: string;
|
|
84
|
+
}>;
|
|
85
|
+
static login(body: {
|
|
86
|
+
email: string;
|
|
87
|
+
password: string;
|
|
88
|
+
csrfToken?: string;
|
|
89
|
+
}, config?: Partial<Config>): Promise<AuthenticationResult>;
|
|
90
|
+
login(body: {
|
|
91
|
+
email: string;
|
|
92
|
+
password: string;
|
|
93
|
+
csrfToken?: string;
|
|
94
|
+
}): Promise<AuthenticationResult>;
|
|
95
|
+
static tokenLogin(token: string, config?: Partial<Config>): Promise<AuthenticationResult>;
|
|
96
|
+
tokenLogin(token: string): Promise<AuthenticationResult>;
|
|
97
|
+
static refresh(refreshToken: string, config?: Partial<Config>): Promise<SessionTokens>;
|
|
98
|
+
refresh(refreshToken: string): Promise<SessionTokens>;
|
|
99
|
+
static register(body: {
|
|
100
|
+
email: string;
|
|
101
|
+
password: string;
|
|
102
|
+
csrfToken?: string;
|
|
103
|
+
}, config?: Partial<Config>): Promise<AuthenticationResult>;
|
|
104
|
+
register(body: {
|
|
105
|
+
email: string;
|
|
106
|
+
password: string;
|
|
107
|
+
csrfToken?: string;
|
|
108
|
+
}): Promise<AuthenticationResult>;
|
|
109
|
+
static resetPassword(body: {
|
|
110
|
+
token: string;
|
|
111
|
+
newPassword: string;
|
|
112
|
+
}, config?: Partial<Config>): Promise<void>;
|
|
113
|
+
resetPassword(body: {
|
|
114
|
+
token: string;
|
|
115
|
+
newPassword: string;
|
|
116
|
+
}): Promise<void>;
|
|
117
|
+
static sendMagicLink(body: {
|
|
118
|
+
email: string;
|
|
119
|
+
csrfToken?: string;
|
|
120
|
+
}, config?: Partial<Config>): Promise<void>;
|
|
121
|
+
sendMagicLink(body: {
|
|
122
|
+
email: string;
|
|
123
|
+
csrfToken?: string;
|
|
124
|
+
}): Promise<void>;
|
|
125
|
+
static sendPasswordReset(body: {
|
|
126
|
+
email: string;
|
|
127
|
+
csrfToken?: string;
|
|
128
|
+
}, config?: Partial<Config>): Promise<void>;
|
|
129
|
+
sendPasswordReset(body: {
|
|
130
|
+
email: string;
|
|
131
|
+
csrfToken?: string;
|
|
132
|
+
}): Promise<void>;
|
|
133
|
+
}
|
|
134
|
+
export {};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
export type ProblemDetails = {
|
|
2
|
+
type: string;
|
|
3
|
+
title: string;
|
|
4
|
+
status: number;
|
|
5
|
+
code?: string;
|
|
6
|
+
detail?: string;
|
|
7
|
+
invalidParams?: {
|
|
8
|
+
in: "body" | "cookie" | "header" | "query" | "path";
|
|
9
|
+
path: string;
|
|
10
|
+
type: string;
|
|
11
|
+
received: unknown;
|
|
12
|
+
expected?: string;
|
|
13
|
+
}[];
|
|
14
|
+
};
|
|
15
|
+
export type ClientId = `cid${string}`;
|
|
16
|
+
export type UserId = `uid${string}`;
|
|
17
|
+
export type AccountId = `acc${string}`;
|
|
18
|
+
export type MembershipId = `mbr${string}`;
|
|
19
|
+
export type AccountStatus = "active" | "trial" | "past_due" | "suspended" | "closed";
|
|
20
|
+
export type AccountResource = {
|
|
21
|
+
id: AccountId;
|
|
22
|
+
name: string | null;
|
|
23
|
+
avatarUrl: string | null;
|
|
24
|
+
status: AccountStatus;
|
|
25
|
+
paidUntil: string | null;
|
|
26
|
+
};
|
|
27
|
+
export type UserStatus = "active" | "trial" | "past_due" | "suspended" | "closed";
|
|
28
|
+
export type UserResource = {
|
|
29
|
+
id: UserId;
|
|
30
|
+
accountId: AccountId;
|
|
31
|
+
status: UserStatus;
|
|
32
|
+
preferredMembershipId: MembershipId | null;
|
|
33
|
+
};
|
|
34
|
+
export type UserIdentity = {
|
|
35
|
+
id: UserId;
|
|
36
|
+
avatarUrl: string | null;
|
|
37
|
+
externalId: string | null;
|
|
38
|
+
givenName: string | null;
|
|
39
|
+
familyName: string | null;
|
|
40
|
+
displayName: string | null;
|
|
41
|
+
preferredLanguage: string | null;
|
|
42
|
+
locale: string | null;
|
|
43
|
+
timezone: string | null;
|
|
44
|
+
};
|
|
45
|
+
export type MembershipRole = "owner" | "member" | "viewer";
|
|
46
|
+
export type Membership = {
|
|
47
|
+
id: MembershipId;
|
|
48
|
+
userId: UserId;
|
|
49
|
+
accountId: AccountId;
|
|
50
|
+
role: MembershipRole;
|
|
51
|
+
};
|
|
52
|
+
export type EmailCredential = {
|
|
53
|
+
id: string;
|
|
54
|
+
email: string | null;
|
|
55
|
+
hashedEmail: string | null;
|
|
56
|
+
hashedPassword: string | null;
|
|
57
|
+
emailVerifiedAt: string | null;
|
|
58
|
+
};
|
|
59
|
+
export type SessionTokens = {
|
|
60
|
+
accessToken: string;
|
|
61
|
+
refreshToken: string;
|
|
62
|
+
tokenType: "Bearer";
|
|
63
|
+
expiresIn: number;
|
|
64
|
+
idToken?: string;
|
|
65
|
+
};
|
|
66
|
+
export type SessionProfile = UserResource & {
|
|
67
|
+
identity: UserIdentity;
|
|
68
|
+
emailCredentials: EmailCredential[];
|
|
69
|
+
memberships: Membership[];
|
|
70
|
+
activeMembership: Membership | null;
|
|
71
|
+
};
|
|
72
|
+
export type AuthenticationResult = {
|
|
73
|
+
session: SessionTokens;
|
|
74
|
+
profile: SessionProfile;
|
|
75
|
+
};
|
|
76
|
+
export type EmailCheckStatus = "active" | "inactive";
|
|
77
|
+
export type LoginMethod = "email_password" | "magic_link";
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@softwarepatterns/am",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Auth client SDK for AccountMaker (Am)",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"authentication",
|
|
7
|
+
"auth",
|
|
8
|
+
"sdk",
|
|
9
|
+
"typescript",
|
|
10
|
+
"oauth",
|
|
11
|
+
"openid-connect",
|
|
12
|
+
"jwt",
|
|
13
|
+
"session-management"
|
|
14
|
+
],
|
|
15
|
+
"author": "Your Name <info@example.com>",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"type": "module",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/softwarepatterns/am/issues"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/softwarepatterns/am.git"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/softwarepatterns/am#readme",
|
|
26
|
+
"sideEffects": false,
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=18"
|
|
29
|
+
},
|
|
30
|
+
"main": "./dist/index.cjs",
|
|
31
|
+
"module": "./dist/index.mjs",
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"import": "./dist/index.mjs",
|
|
37
|
+
"require": "./dist/index.cjs"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist"
|
|
42
|
+
],
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build:clean": "rm -rf dist",
|
|
45
|
+
"build": "npm run build:clean && rollup -c",
|
|
46
|
+
"prepublishOnly": "npm run check",
|
|
47
|
+
"test:unit": "bun test src",
|
|
48
|
+
"test:integration": "NODE_TLS_REJECT_UNAUTHORIZED=0 bun test test/integration",
|
|
49
|
+
"typecheck": "bunx tsc --noEmit",
|
|
50
|
+
"check": "npm run typecheck && npm run build",
|
|
51
|
+
"digest": "bunx ai-digest -i . -o codebase.md --whitespace-removal --show-output-files"
|
|
52
|
+
},
|
|
53
|
+
"publishConfig": {
|
|
54
|
+
"access": "public"
|
|
55
|
+
}
|
|
56
|
+
}
|