@medusajs/user 2.22.0-snapshot-20261020204851 → 2.22.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.
Files changed (3) hide show
  1. package/AGENTS.md +75 -0
  2. package/README.md +87 -2
  3. package/package.json +8 -4
package/AGENTS.md ADDED
@@ -0,0 +1,75 @@
1
+ # @medusajs/user
2
+
3
+ Commerce module for admin users and user invites, including signing and validating JWT invite tokens. Authentication itself lives in the Auth Module. Registered as `Modules.USER` (`"user"`).
4
+
5
+ ## Using this package
6
+
7
+ - Loaded by default through `defineConfig` (`@medusajs/medusa/user`), which passes the options from `projectConfig.http` (`jwtSecret` or `JWT_SECRET`, `jwtOptions`, `jwtVerifyOptions`, `jwtPublicKey`). Override only to change invite behavior:
8
+
9
+ ```ts
10
+ module.exports = defineConfig({
11
+ modules: [
12
+ {
13
+ resolve: "@medusajs/medusa/user",
14
+ options: {
15
+ jwt_secret: process.env.JWT_SECRET,
16
+ valid_duration: 60 * 60 * 24, // invite TTL in seconds
17
+ },
18
+ },
19
+ ],
20
+ })
21
+ ```
22
+
23
+ - Options read by the service constructor: `jwt_secret` (required, the module throws `INVALID_DATA` without it), `jwt_public_key`, `jwt_options` (jsonwebtoken `SignOptions`), `jwt_verify_options`, `valid_duration` (seconds; falls back to `jwt_options.expiresIn`, then 24 hours).
24
+ - In apps, prefer the core-flows workflows: `createUsersWorkflow`, `updateUsersWorkflow`, `deleteUsersWorkflow`, `createUserAccountWorkflow`, `removeUserAccountWorkflow`, `createInvitesWorkflow`, `acceptInviteWorkflow`, `refreshInviteTokensWorkflow`, `deleteInvitesWorkflow`, and RBAC ones (`assignUserRolesWorkflow`, `removeUserRolesWorkflow`).
25
+
26
+ ```ts
27
+ import { Modules } from "@medusajs/framework/utils"
28
+ import type { IUserModuleService } from "@medusajs/framework/types"
29
+
30
+ const userModuleService: IUserModuleService = container.resolve(Modules.USER)
31
+ const invite = await userModuleService.validateInviteToken(token)
32
+ ```
33
+
34
+ ### Data models (`src/models`)
35
+
36
+ - `User` (`user_`): `first_name`, `last_name`, `email` (unique among non-deleted), `avatar_url`, `metadata`.
37
+ - `Invite` (`invite_`): `email` (unique among non-deleted), `accepted`, `token`, `expires_at`, `metadata`.
38
+
39
+ ### Service methods (`src/services/user-module.ts`)
40
+
41
+ Generated CRUD for both models, plus:
42
+
43
+ - `validateInviteToken(token)`: verifies the JWT, loads the invite, and checks the token matches the stored one and is not expired.
44
+ - `refreshInviteTokens(inviteIds)`: issues new tokens and `expires_at`.
45
+ - Overridden `createUsers`, `updateUsers`, `createInvites` (generates token and expiry), `updateInvites`.
46
+
47
+ ### Events and links
48
+
49
+ - Internal CRUD events plus `user.user.invite.token_generated` (`UserEvents.INVITE_TOKEN_GENERATED` from `@medusajs/framework/utils`), emitted by `createInvites`, `updateInvites`, and `refreshInviteTokens`.
50
+ - Workflow events: `user.created|updated|deleted` (`UserWorkflowEvents`) and `invite.created|accepted|deleted|resent` (`InviteWorkflowEvents`).
51
+ - Module links: `user-rbac-role` (`user_rbac_role`) and `invite-rbac-role` (`invite_rbac_role`) to the RBAC Module.
52
+
53
+ Docs: https://docs.medusajs.com/resources/commerce-modules/user.md, https://docs.medusajs.com/resources/commerce-modules/user/module-options.md, https://docs.medusajs.com/resources/commerce-modules/user/user-creation-flows.md, https://docs.medusajs.com/resources/commerce-modules/user/invite-user-subscriber.md
54
+
55
+ ## Architecture
56
+
57
+ - Tokens are signed in `generateToken` with `jwt_secret` and `jwt_options` (a random `jwtid` per token unless set). Verification uses `jwt_public_key ?? jwt_secret` and `jwt_verify_options ?? jwt_options`; a single `algorithm` option is converted to `algorithms` for verification.
58
+ - `getExpiresAt` in `src/utils/utils.ts` accepts seconds (number) or a timespan string.
59
+
60
+ ## Development
61
+
62
+ ```bash
63
+ cd packages/modules/user
64
+ yarn build
65
+ yarn test
66
+ yarn test:integration # integration-tests/__tests__/{user,invite}.spec.ts (needs Postgres, DB_* env vars)
67
+ yarn migration:create # after any change in src/models
68
+ ```
69
+
70
+ ## Gotchas
71
+
72
+ - The constructor's second parameter is named `moduleDeclaration` but holds the module options; option keys are snake_case.
73
+ - A refreshed (resent) invite invalidates earlier tokens: `validateInviteToken` rejects any token not equal to the stored `invite.token`.
74
+ - `createInvites` throws `INVALID_DATA` when a user with the email already exists.
75
+ - `updateInvites` emits `INVITE_TOKEN_GENERATED` on every update, even when the token didn't change.
package/README.md CHANGED
@@ -1,3 +1,88 @@
1
- # User Module
1
+ <p align="center">
2
+ <a href="https://www.medusajs.com">
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/59018053/229103275-b5e482bb-4601-46e6-8142-244f531cebdb.svg">
5
+ <source media="(prefers-color-scheme: light)" srcset="https://user-images.githubusercontent.com/59018053/229103726-e5b529a3-9b3f-4970-8a1f-c6af37f087bf.svg">
6
+ <img alt="Medusa logo" src="https://user-images.githubusercontent.com/59018053/229103726-e5b529a3-9b3f-4970-8a1f-c6af37f087bf.svg">
7
+ </picture>
8
+ </a>
9
+ </p>
10
+ <h1 align="center">
11
+ @medusajs/user
12
+ </h1>
2
13
 
3
- The User Module is Medusa’s user engine.
14
+ <h4 align="center">
15
+ <a href="https://docs.medusajs.com">Documentation</a> |
16
+ <a href="https://www.medusajs.com">Website</a>
17
+ </h4>
18
+
19
+ <p align="center">
20
+ Building blocks for digital commerce
21
+ </p>
22
+ <p align="center">
23
+ <a href="https://github.com/medusajs/medusa/blob/develop/LICENSE">
24
+ <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="Medusa is released under the MIT license." />
25
+ </a>
26
+ <a href="https://github.com/medusajs/medusa/blob/develop/CONTRIBUTING.md">
27
+ <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" alt="PRs welcome!" />
28
+ </a>
29
+ <a href="https://discord.gg/xpCwq3Kfn8">
30
+ <img src="https://img.shields.io/badge/chat-on%20discord-7289DA.svg" alt="Discord Chat" />
31
+ </a>
32
+ <a href="https://twitter.com/intent/follow?screen_name=medusajs">
33
+ <img src="https://img.shields.io/twitter/follow/medusajs.svg?label=Follow%20@medusajs" alt="Follow @medusajs" />
34
+ </a>
35
+ </p>
36
+
37
+ User Module for Medusa: manages admin users and invites, including generating and validating invite tokens. It's installed and registered by default with `@medusajs/medusa`, which passes it the JWT settings from your project config, so Medusa applications use it through the `Modules.USER` service rather than installing this package directly.
38
+
39
+ ## At a glance
40
+
41
+ | | |
42
+ | --- | --- |
43
+ | Package | `@medusajs/user` |
44
+ | Type | Commerce Module |
45
+ | Module key | `Modules.USER` (`"user"`) |
46
+ | Registered by default | Yes |
47
+ | Import from | `@medusajs/medusa/user` |
48
+
49
+ ## Installation
50
+
51
+ No installation needed. The module ships with `@medusajs/medusa` and is registered by `defineConfig`.
52
+
53
+ ## Usage
54
+
55
+ To customize the module's options, such as the invite token's validity, register it in `medusa-config.ts`:
56
+
57
+ ```ts
58
+ import { defineConfig } from "@medusajs/framework/utils"
59
+
60
+ module.exports = defineConfig({
61
+ // ...
62
+ modules: [
63
+ {
64
+ resolve: "@medusajs/medusa/user",
65
+ options: {
66
+ jwt_secret: process.env.JWT_SECRET,
67
+ valid_duration: 60 * 60 * 24,
68
+ },
69
+ },
70
+ ],
71
+ })
72
+ ```
73
+
74
+ ## Configuration
75
+
76
+ | Option | Type | Description | Default |
77
+ | --- | --- | --- | --- |
78
+ | `jwt_secret` | `string` | Secret used to sign invite tokens (or the private key when using asymmetric signing). Required: the module throws on startup if it's missing. | `projectConfig.http.jwtSecret`, then the `JWT_SECRET` environment variable (set by `defineConfig`) |
79
+ | `jwt_public_key` | `string` | Public key used to verify invite tokens when using asymmetric signing. | `projectConfig.http.jwtPublicKey` (set by `defineConfig`) |
80
+ | `valid_duration` | `number` | How long an invite token is valid, in seconds. | `jwt_options.expiresIn`, then `86400` (24 hours) |
81
+ | `jwt_options` | `object` | [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken) sign options, such as `algorithm`. | `projectConfig.http.jwtOptions` (set by `defineConfig`) |
82
+ | `jwt_verify_options` | `object` | jsonwebtoken verify options, such as `algorithms`. Falls back to `jwt_options` when not set. | `projectConfig.http.jwtVerifyOptions` (set by `defineConfig`) |
83
+
84
+ ## Resources
85
+
86
+ - [User Module](https://docs.medusajs.com/resources/commerce-modules/user)
87
+ - [Module Options](https://docs.medusajs.com/resources/commerce-modules/user/module-options)
88
+ - [User Creation Flows](https://docs.medusajs.com/resources/commerce-modules/user/user-creation-flows)
package/package.json CHANGED
@@ -1,15 +1,19 @@
1
1
  {
2
2
  "name": "@medusajs/user",
3
- "version": "2.22.0-snapshot-20261020204851",
3
+ "version": "2.22.0",
4
4
  "description": "Medusa Users module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": [
8
8
  "dist",
9
+ "AGENTS.md",
9
10
  "!dist/**/__tests__",
10
11
  "!dist/**/__mocks__",
11
12
  "!dist/**/__fixtures__"
12
13
  ],
14
+ "llms": "https://docs.medusajs.com/llms.txt",
15
+ "llmsFull": "https://docs.medusajs.com/llms-full.txt",
16
+ "mcpServer": "https://docs.medusajs.com/mcp",
13
17
  "engines": {
14
18
  "node": ">=22.22.0"
15
19
  },
@@ -39,13 +43,13 @@
39
43
  "orm:cache:clear": "MIKRO_ORM_CLI_CONFIG=./mikro-orm.config.dev.ts MIKRO_ORM_ALLOW_GLOBAL_CLI=true medusa-mikro-orm cache:clear"
40
44
  },
41
45
  "devDependencies": {
42
- "@medusajs/framework": "2.22.0-snapshot-20261020204851",
43
- "@medusajs/test-utils": "2.22.0-snapshot-20261020204851"
46
+ "@medusajs/framework": "2.22.0",
47
+ "@medusajs/test-utils": "2.22.0"
44
48
  },
45
49
  "dependencies": {
46
50
  "jsonwebtoken": "^9.0.2"
47
51
  },
48
52
  "peerDependencies": {
49
- "@medusajs/framework": "2.22.0-snapshot-20261020204851"
53
+ "@medusajs/framework": "2.22.0"
50
54
  }
51
55
  }