@productcraft/platform-auth 0.0.2 → 0.0.4
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 +219 -0
- package/dist/index.d.cts +1092 -114
- package/dist/index.d.ts +1092 -114
- package/package.json +3 -3
package/README.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# @productcraft/platform-auth
|
|
2
|
+
|
|
3
|
+
Typed Node.js SDK for [ProductCraft Platform-Auth](https://productcraft.co) — PlatformUser sign-in / sign-up / password reset, workspaces, members + invites, workspace roles + IAM policies, workspace API keys, service activation, and the `/v1/introspect` endpoint every other ProductCraft backend uses to resolve permissions.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install @productcraft/platform-auth
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Server-side only. The SDK ships a Platform API Key in the `Authorization` header — never embed it in a browser bundle.
|
|
10
|
+
|
|
11
|
+
## Which SDK do I want?
|
|
12
|
+
|
|
13
|
+
| If your goal is to … | Reach for |
|
|
14
|
+
|---|---|
|
|
15
|
+
| Authenticate **your own end-users** in a product you're building (Heimdall apps) | [`@productcraft/heimdall`](https://www.npmjs.com/package/@productcraft/heimdall) |
|
|
16
|
+
| Authenticate **your team** into the ProductCraft console + manage workspaces | **this package** |
|
|
17
|
+
|
|
18
|
+
The two are easy to confuse because both have "auth" in the name. Platform-Auth owns *the ProductCraft account you use to log into productcraft.co*. Heimdall owns *the end-users of products you build on the platform*. Distinct databases, distinct signing keys.
|
|
19
|
+
|
|
20
|
+
## Quick start
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { PlatformAuth } from "@productcraft/platform-auth";
|
|
24
|
+
|
|
25
|
+
const platformAuth = new PlatformAuth({
|
|
26
|
+
auth: { type: "apiKey", key: process.env.PCFT_KEY! },
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Resolve the caller's effective policy + enabled services for a workspace
|
|
30
|
+
const { data } = await platformAuth.client.GET(
|
|
31
|
+
"/v1/introspect/workspaces/{workspace_id}",
|
|
32
|
+
{ params: { path: { workspace_id: "ws_..." } } },
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
// data.policy.statements[…] — what the caller is allowed to do
|
|
36
|
+
// data.enabled_services[…] — envoi / rally / agora / heimdall / …
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The `client` is an [`openapi-fetch`](https://openapi-ts.dev/openapi-fetch/) instance bound to `https://api.auth.productcraft.co` and your auth credential.
|
|
40
|
+
|
|
41
|
+
## Configuration
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
new PlatformAuth({
|
|
45
|
+
auth: { type: "apiKey", key: "pcft_live_..." }
|
|
46
|
+
| { type: "bearer", token: "eyJ..." }
|
|
47
|
+
| { type: "cookie", value: "auth_token=..." },
|
|
48
|
+
baseUrl: "https://api.auth.example.test", // optional override
|
|
49
|
+
fetch: customFetch, // optional
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Common operations
|
|
54
|
+
|
|
55
|
+
### Authentication (PlatformUser sign-in)
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
// Sign in
|
|
59
|
+
await platformAuth.client.POST(
|
|
60
|
+
"/v1/auth/signin",
|
|
61
|
+
{ body: { identifier: "you@example.com", password: "..." } },
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
// Refresh tokens
|
|
65
|
+
await platformAuth.client.POST("/v1/auth/refresh", { body: { refresh_token } });
|
|
66
|
+
|
|
67
|
+
// Logout (single session) — or /v1/auth/logout to revoke every refresh token
|
|
68
|
+
await platformAuth.client.POST("/v1/auth/logout-current", { body: { refresh_token } });
|
|
69
|
+
|
|
70
|
+
// Password reset
|
|
71
|
+
await platformAuth.client.POST(
|
|
72
|
+
"/v1/auth/password/request-reset",
|
|
73
|
+
{ body: { email: "you@example.com" } },
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
await platformAuth.client.POST(
|
|
77
|
+
"/v1/auth/password/reset",
|
|
78
|
+
{ body: { token, new_password: "..." } },
|
|
79
|
+
);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Introspect — used by every other ProductCraft backend
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
// Resolve the bearer of a token: returns account + email_verified_at + workspaces
|
|
86
|
+
await platformAuth.client.GET("/v1/introspect");
|
|
87
|
+
|
|
88
|
+
// Resolve effective policy + enabled services for one workspace
|
|
89
|
+
await platformAuth.client.GET(
|
|
90
|
+
"/v1/introspect/workspaces/{workspace_id}",
|
|
91
|
+
{ params: { path: { workspace_id: "ws_..." } } },
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
// Resolve a PAK — used internally by services that accept pcft_live_* on routes
|
|
95
|
+
await platformAuth.client.GET("/v1/introspect/api-key");
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The latter two are cached by every consuming service for ~60 seconds. Reach for them from a backend gate; never from a hot request path.
|
|
99
|
+
|
|
100
|
+
### Workspaces
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
// List
|
|
104
|
+
await platformAuth.client.GET("/v1/workspaces");
|
|
105
|
+
|
|
106
|
+
// Create
|
|
107
|
+
await platformAuth.client.POST(
|
|
108
|
+
"/v1/workspaces",
|
|
109
|
+
{ body: { name: "Acme", slug: "acme" } },
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
// Get / update / delete by slug
|
|
113
|
+
await platformAuth.client.GET("/v1/workspaces/{workspace_slug}", { ... });
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Members, invites, roles
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
// Members
|
|
120
|
+
await platformAuth.client.GET("/v1/workspaces/{workspace_slug}/members", { ... });
|
|
121
|
+
await platformAuth.client.PATCH(
|
|
122
|
+
"/v1/workspaces/{workspace_slug}/members/{account_id}/role",
|
|
123
|
+
{ params: { ... }, body: { role_id: "role_..." } },
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
// Invites
|
|
127
|
+
await platformAuth.client.POST(
|
|
128
|
+
"/v1/workspaces/{workspace_slug}/invites",
|
|
129
|
+
{ params: { ... }, body: { email: "...", role_id: "..." } },
|
|
130
|
+
);
|
|
131
|
+
await platformAuth.client.POST("/v1/workspaces/invites/accept", { body: { code } });
|
|
132
|
+
|
|
133
|
+
// Roles
|
|
134
|
+
await platformAuth.client.POST(
|
|
135
|
+
"/v1/workspaces/{workspace_slug}/roles",
|
|
136
|
+
{ params: { ... }, body: { name: "billing-admin", policy_ids: ["pol_..."] } },
|
|
137
|
+
);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### IAM policies
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
// List the canonical permission catalogue (what verbs exist for each service)
|
|
144
|
+
await platformAuth.client.GET(
|
|
145
|
+
"/v1/workspaces/{workspace_slug}/policies/actions/catalog",
|
|
146
|
+
{ ... },
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
// Create a custom policy
|
|
150
|
+
await platformAuth.client.POST(
|
|
151
|
+
"/v1/workspaces/{workspace_slug}/policies",
|
|
152
|
+
{
|
|
153
|
+
params: { ... },
|
|
154
|
+
body: {
|
|
155
|
+
name: "Envoi-read-only",
|
|
156
|
+
statements: [
|
|
157
|
+
{ effect: "allow", actions: ["envoi.read", "envoi.list"], resources: ["*"] },
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
);
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Workspace API keys (PATs)
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
// Mint a PAK for CI / IaC
|
|
168
|
+
await platformAuth.client.POST(
|
|
169
|
+
"/v1/workspaces/{workspace_slug}/api-keys",
|
|
170
|
+
{ params: { ... }, body: { name: "github-actions", policy_ids: ["pol_..."] } },
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
// Bind / unbind a PAK to additional workspaces (rare — most PAKs stay
|
|
174
|
+
// scoped to the workspace they were minted under)
|
|
175
|
+
await platformAuth.client.PUT(
|
|
176
|
+
"/v1/workspaces/{workspace_slug}/api-keys/{id}/bindings",
|
|
177
|
+
{ ... },
|
|
178
|
+
);
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Service activation
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
// Enable / disable a service for the workspace (envoi, rally, agora, heimdall, …)
|
|
185
|
+
await platformAuth.client.PUT(
|
|
186
|
+
"/v1/workspaces/{workspace_slug}/services/{service}",
|
|
187
|
+
{ params: { ... }, body: { enabled: true } },
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
// Per-service workspace settings
|
|
191
|
+
await platformAuth.client.PUT(
|
|
192
|
+
"/v1/workspaces/{workspace_slug}/services/{service}/settings",
|
|
193
|
+
{ ... },
|
|
194
|
+
);
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Audit
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
// Read the workspace audit log
|
|
201
|
+
await platformAuth.client.GET(
|
|
202
|
+
"/v1/workspaces/{workspace_slug}/audit-logs",
|
|
203
|
+
{ params: { ... }, query: { limit: 100 } },
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
// Streaming-friendly "recent activity" feed (for the console UI)
|
|
207
|
+
await platformAuth.client.GET(
|
|
208
|
+
"/v1/workspaces/{workspace_slug}/audit-feed",
|
|
209
|
+
{ ... },
|
|
210
|
+
);
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## How this SDK is built
|
|
214
|
+
|
|
215
|
+
Generated from the live OpenAPI spec at `https://api.auth.productcraft.co/docs-json` via [`openapi-typescript`](https://openapi-ts.dev/) + [`openapi-fetch`](https://openapi-ts.dev/openapi-fetch/). The nightly `spec-refresh` workflow opens a PR whenever the spec changes.
|
|
216
|
+
|
|
217
|
+
## License
|
|
218
|
+
|
|
219
|
+
[MIT](https://github.com/clauderanelagh/productcraft-node/blob/main/LICENSE).
|