idp-admin 0.1.1 → 0.1.2

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.
Files changed (2) hide show
  1. package/README.md +78 -7
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -6,13 +6,7 @@ Apps that sign people in through an identity provider (Cognito, Keycloak, Entra
6
6
 
7
7
  idp-admin is that layer, written once.
8
8
 
9
- > **Status:** 0.x, so the API may still change between minor versions. The adapters are published and usable directly; `IdpAdmin`, the class that adds the shared rules on top of them (including the access-reduced hook below), isn't built yet.
10
-
11
- ```sh
12
- npm install idp-admin
13
- ```
14
-
15
- The reference for every entry point is in [docs](docs/index.md).
9
+ > **Status:** 0.x, so the API may still change between minor versions. The adapters are published and usable directly; `IdpAdmin`, the class that adds the shared rules on top of them (including the access-reduced hook below), isn't built yet. See the [quick start](#quick-start) and the [reference](docs/index.md).
16
10
 
17
11
  ## Why it exists
18
12
 
@@ -41,6 +35,83 @@ This package came out of exactly that situation: two production apps, each with
41
35
  - **Not a lowest common denominator.** Providers differ, and some features don't exist everywhere. Adapters declare what they support, and you can always reach the provider's own SDK for anything the shared interface doesn't cover.
42
36
  - **Not a UI.** It's the server-side layer an admin screen, a background job or a seed script would call.
43
37
 
38
+ ## Quick start
39
+
40
+ ```sh
41
+ npm install idp-admin
42
+ npm install @aws-sdk/client-cognito-identity-provider # only for Cognito
43
+ ```
44
+
45
+ Pick an adapter for your provider. Each one's setup (credentials, permissions, realm or pool settings) is in its doc: [Cognito](docs/cognito.md), [Keycloak](docs/keycloak.md), [fake](docs/fake.md).
46
+
47
+ ```ts
48
+ import type { IdpAdapter } from "idp-admin"
49
+ import { CognitoAdapter } from "idp-admin/cognito"
50
+ import { KeycloakAdapter } from "idp-admin/keycloak"
51
+
52
+ // Cognito in production, Keycloak in a container locally: the rest of the app doesn't know which
53
+ const idp: IdpAdapter<"company"> = process.env.COGNITO_USER_POOL_ID
54
+ ? new CognitoAdapter({
55
+ userPoolId: process.env.COGNITO_USER_POOL_ID,
56
+ region: "us-east-1",
57
+ attributes: { company: "custom:companyName" },
58
+ })
59
+ : new KeycloakAdapter({
60
+ issuer: "http://localhost:8080/realms/acme",
61
+ clientId: "acme-admin",
62
+ clientSecret: process.env.KEYCLOAK_ADMIN_SECRET!,
63
+ attributes: { company: "companyName" },
64
+ })
65
+ ```
66
+
67
+ `attributes` maps the names your app uses to the provider's own, and only those names compile.
68
+
69
+ ```ts
70
+ import { UserExistsError } from "idp-admin"
71
+
72
+ // create a user who must set their own password at first sign-in; send them the temporary one yourself
73
+ try{
74
+ const user = await idp.createUser({
75
+ email: "dana@example.com",
76
+ name: "Dana Lee",
77
+ attributes: { company: "Acme" },
78
+ temporaryPassword: "Temp-pass-1!",
79
+ })
80
+ if(!(await idp.groupExists("admins"))) await idp.createGroup("admins")
81
+ await idp.addToGroup(user.id, "admins")
82
+ }catch(error){
83
+ if(error instanceof UserExistsError) console.log("already invited")
84
+ else throw error
85
+ }
86
+
87
+ // take access away, and end the sessions the provider already issued
88
+ const dana = await idp.findUserByEmail("dana@example.com")
89
+ if(dana){
90
+ await idp.setEnabled(dana.id, false)
91
+ await idp.signOutEverywhere(dana.id)
92
+ }
93
+
94
+ // list everyone, a page at a time
95
+ let cursor: string | null = null
96
+ do{
97
+ const page = await idp.listUsersPage(cursor)
98
+ for(const user of page.items) console.log(user.email, user.status, user.enabled)
99
+ cursor = page.nextCursor
100
+ }while(cursor)
101
+ ```
102
+
103
+ A user's `id` is the `sub` in their sign-in tokens, so it matches what your auth library gives you. Pass emails lowercased and trimmed, and `findUserByEmail` returns `null` while `getUser` throws `UserNotFoundError`. The full list of methods, types and errors is in [docs/index.md](docs/index.md).
104
+
105
+ In tests, use the fake instead. It keeps everything in memory and records what a real provider would have done:
106
+
107
+ ```ts
108
+ import { FakeAdapter } from "idp-admin/fake"
109
+
110
+ const fake = new FakeAdapter({ attributes: ["company"] })
111
+ // ...run the code under test with `fake` as its IdpAdapter, then:
112
+ expect(fake.signOuts).toContain(userId)
113
+ ```
114
+
44
115
  ## Providers
45
116
 
46
117
  Cognito, Keycloak and the fake provider are included today: the ones we run in production and can test properly.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "idp-admin",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "One user-management API for any identity provider.",
5
5
  "keywords": [
6
6
  "identity-provider",