@gravito/satellite-membership 0.1.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.
Files changed (50) hide show
  1. package/.dockerignore +8 -0
  2. package/.env.example +19 -0
  3. package/ARCHITECTURE.md +14 -0
  4. package/CHANGELOG.md +14 -0
  5. package/Dockerfile +25 -0
  6. package/README.md +112 -0
  7. package/WHITEPAPER.md +20 -0
  8. package/dist/index.d.ts +26 -0
  9. package/dist/index.js +1121 -0
  10. package/docs/EXTENDING.md +99 -0
  11. package/docs/PASSKEYS.md +78 -0
  12. package/locales/en.json +30 -0
  13. package/locales/zh-TW.json +30 -0
  14. package/package.json +35 -0
  15. package/src/Application/DTOs/MemberDTO.ts +34 -0
  16. package/src/Application/Mail/ForgotPasswordMail.ts +42 -0
  17. package/src/Application/Mail/MemberLevelChangedMail.ts +41 -0
  18. package/src/Application/Mail/WelcomeMail.ts +45 -0
  19. package/src/Application/Services/PasskeysService.ts +198 -0
  20. package/src/Application/UseCases/ForgotPassword.ts +34 -0
  21. package/src/Application/UseCases/LoginMember.ts +64 -0
  22. package/src/Application/UseCases/RegisterMember.ts +65 -0
  23. package/src/Application/UseCases/ResetPassword.ts +30 -0
  24. package/src/Application/UseCases/UpdateMemberLevel.ts +47 -0
  25. package/src/Application/UseCases/UpdateSettings.ts +81 -0
  26. package/src/Application/UseCases/VerifyEmail.ts +23 -0
  27. package/src/Domain/Contracts/IMemberPasskeyRepository.ts +8 -0
  28. package/src/Domain/Contracts/IMemberRepository.ts +11 -0
  29. package/src/Domain/Entities/Member.ts +219 -0
  30. package/src/Domain/Entities/MemberPasskey.ts +97 -0
  31. package/src/Infrastructure/Auth/SentinelMemberProvider.ts +52 -0
  32. package/src/Infrastructure/Persistence/AtlasMemberPasskeyRepository.ts +63 -0
  33. package/src/Infrastructure/Persistence/AtlasMemberRepository.ts +91 -0
  34. package/src/Infrastructure/Persistence/Migrations/20250101_create_members_table.ts +30 -0
  35. package/src/Infrastructure/Persistence/Migrations/20250102_create_member_passkeys_table.ts +25 -0
  36. package/src/Interface/Http/Controllers/PasskeyController.ts +98 -0
  37. package/src/Interface/Http/Middleware/VerifySingleDevice.ts +51 -0
  38. package/src/index.ts +234 -0
  39. package/src/manifest.json +15 -0
  40. package/tests/PasskeysService.test.ts +113 -0
  41. package/tests/email-integration.test.ts +161 -0
  42. package/tests/grand-review.ts +176 -0
  43. package/tests/integration.test.ts +75 -0
  44. package/tests/member.test.ts +47 -0
  45. package/tests/unit.test.ts +7 -0
  46. package/tests/update-settings.test.ts +101 -0
  47. package/tsconfig.json +26 -0
  48. package/views/emails/level_changed.html +35 -0
  49. package/views/emails/reset_password.html +34 -0
  50. package/views/emails/welcome.html +31 -0
package/.dockerignore ADDED
@@ -0,0 +1,8 @@
1
+ node_modules
2
+ dist
3
+ .git
4
+ .env
5
+ *.log
6
+ .vscode
7
+ .idea
8
+ tests
package/.env.example ADDED
@@ -0,0 +1,19 @@
1
+ # Application
2
+ APP_NAME="membership"
3
+ APP_ENV=development
4
+ APP_KEY=
5
+ APP_DEBUG=true
6
+ APP_URL=http://localhost:3000
7
+
8
+ # Server
9
+ PORT=3000
10
+
11
+ # Database
12
+ DB_CONNECTION=sqlite
13
+ DB_DATABASE=database/database.sqlite
14
+
15
+ # Cache
16
+ CACHE_DRIVER=memory
17
+
18
+ # Logging
19
+ LOG_LEVEL=debug
@@ -0,0 +1,14 @@
1
+ # membership Satellite Architecture
2
+
3
+ This satellite follows the Gravito Satellite Specification v1.0.
4
+
5
+ ## Design
6
+ - **DDD**: Domain logic is separated from framework concerns.
7
+ - **Dogfooding**: Uses official Gravito modules (@gravito/atlas, @gravito/stasis).
8
+ - **Decoupled**: Inter-satellite communication happens via Contracts and Events.
9
+
10
+ ## Layers
11
+ - **Domain**: Pure business rules.
12
+ - **Application**: Orchestration of domain tasks.
13
+ - **Infrastructure**: Implementation of persistence and external services.
14
+ - **Interface**: HTTP and Event entry points.
package/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ # @gravito/satellite-membership
2
+
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @gravito/atlas@1.0.1
9
+ - @gravito/core@1.0.0
10
+ - @gravito/cosmos@1.0.0
11
+ - @gravito/enterprise@1.0.0
12
+ - @gravito/sentinel@1.0.0
13
+ - @gravito/signal@1.0.0
14
+ - @gravito/stasis@1.0.0
package/Dockerfile ADDED
@@ -0,0 +1,25 @@
1
+ FROM oven/bun:1.0 AS base
2
+ WORKDIR /usr/src/app
3
+
4
+ # Install dependencies
5
+ FROM base AS install
6
+ RUN mkdir -p /temp/dev
7
+ COPY package.json bun.lockb /temp/dev/
8
+ RUN cd /temp/dev && bun install --frozen-lockfile
9
+
10
+ # Build application
11
+ FROM base AS build
12
+ COPY --from=install /temp/dev/node_modules node_modules
13
+ COPY . .
14
+ ENV NODE_ENV=production
15
+ RUN bun run build
16
+
17
+ # Final production image
18
+ FROM base AS release
19
+ COPY --from=build /usr/src/app/dist/bootstrap.js index.js
20
+ COPY --from=build /usr/src/app/package.json .
21
+
22
+ # Create a non-root user for security
23
+ USER bun
24
+ EXPOSE 3000/tcp
25
+ ENTRYPOINT [ "bun", "run", "index.js" ]
package/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # 🛰️ Gravito Membership Satellite
2
+
3
+ 這是 Gravito 生態系中的標準會員管理衛星模組(Satellite)。基於 **DDD (領域驅動設計)** 與 **Galaxy Architecture** 構建,專為高效能、高擴展性與 Bun 原生環境優化。
4
+
5
+ ## ✨ 核心功能
6
+
7
+ - **身分驗證 (Auth)**: 整合 Sentinel 模組,支援 Session 登入與 **持久化 (Remember Me)**。
8
+ - **註冊流程**: 包含自動生成驗證權杖與電子郵件發送 Hook。
9
+ - **安全防護**:
10
+ - **多設備登入限制 (Single Device Login)**: 可開關功能,自動註冊並踢除舊裝置。
11
+ - **密碼安全**: 使用 Bun 原生加密,支援自動 Rehash。
12
+ - **Passkeys (WebAuthn)**: 內建 Passkeys 登錄 + 登入 API,可配合 `@simplewebauthn/browser` 與瀏覽器原生驗證器。
13
+ - **美化郵件 (Beautiful Emails)**:
14
+ - 使用 Prism 模板引擎。
15
+ - 支援現代化 HTML 佈局。
16
+ - 完整多語系支持 (i18n)。
17
+ - **動態 Metadata**: 會員實體支援無 Schema 的元數據擴展,適合電商、訂閱制等場景。
18
+
19
+ ## 🚀 快速開始
20
+
21
+ ... (內容省略) ...
22
+
23
+ ## 🛠️ 擴充與自定義 (DX Guide)
24
+
25
+ 想要自定義品牌、覆寫郵件樣式或增加業務邏輯?請參考我們的:
26
+ 👉 [**Membership 擴充與自定義指南 (EXTENDING.md)**](./docs/EXTENDING.md)
27
+
28
+ 想要使用 Passkeys?請參考:
29
+ 👉 [**Passkeys Integration Guide (PASSKEYS.md)**](./docs/PASSKEYS.md)
30
+
31
+ ## ⚙️ 配置選項
32
+
33
+ 在 `core` 配置中調整以下開關:
34
+
35
+ ```typescript
36
+ {
37
+ membership: {
38
+ auth: {
39
+ // 是否限制帳號只能在單一裝置登入
40
+ single_device: true,
41
+ // 是否啟用持久化登入 (Remember Me)
42
+ remember_me: true
43
+ },
44
+ branding: {
45
+ name: 'Your Project Name',
46
+ primary_color: '#3b82f6' // Tailwind Blue 500
47
+ }
48
+ },
49
+ app: {
50
+ url: 'https://yourapp.com'
51
+ }
52
+ }
53
+ ```
54
+
55
+ ## 🎨 自定義模板
56
+
57
+ 本模組提供預設的郵件模板。如果您想更換設計,只需在您的專案中建立以下檔案,Prism 會優先使用您的檔案:
58
+
59
+ - `views/emails/welcome.html`
60
+ - `views/emails/reset_password.html`
61
+ - `views/emails/level_changed.html`
62
+
63
+ 模板中可以使用 `{{ branding.name }}` 和 `{{ branding.color }}` 來保持一致性。
64
+
65
+ 本模組不強制綁定郵件驅動,而是透過 Hook 觸發動作。若您啟用了 `OrbitSignal`,本模組會自動處理以下 Hook:
66
+
67
+ - `membership:send-verification`: 發送註冊驗證郵件。
68
+ - `membership:send-reset-password`: 發送密碼重設郵件。
69
+ - `membership:level-changed`: 當會員等級提升時發送慶祝郵件。
70
+
71
+ ## 📦 隊列整合 (Queue Integration)
72
+
73
+ 為了獲得最佳效能,建議掛載 `OrbitStream` 來啟用非同步發信。本模組已預設呼叫 `mail.queue()`。
74
+
75
+ ### 1. 安裝隊列軌道
76
+ ```typescript
77
+ import { OrbitStream } from '@gravito/stream'
78
+
79
+ await core.orbit(new OrbitStream({
80
+ default: 'redis',
81
+ connections: {
82
+ redis: { driver: 'redis', host: 'localhost' }
83
+ }
84
+ }))
85
+ ```
86
+
87
+ ### 2. 運作原理
88
+ - **有隊列時**: 郵件動作會被推入 `default` 隊列,API 請求會立即回傳。
89
+ - **無隊列時**: 系統會自動降級為同步發送(Sync Send),確保功能不中斷。
90
+
91
+ ## 🛠️ API 使用範例
92
+
93
+ ### 會員註冊
94
+ ```typescript
95
+ const register = container.make('membership.register')
96
+ await register.execute({
97
+ name: 'Carl',
98
+ email: 'carl@example.com',
99
+ passwordPlain: 'secret123'
100
+ })
101
+ ```
102
+
103
+ ### 多設備登入檢查 (Middleware)
104
+ 您可以將此中間件應用於敏感路由:
105
+ ```typescript
106
+ import { verifySingleDevice } from '@gravito/satellite-membership/middleware'
107
+
108
+ router.get('/profile', verifySingleDevice, (c) => { ... })
109
+ ```
110
+
111
+ ## 📄 授權
112
+ MIT License
package/WHITEPAPER.md ADDED
@@ -0,0 +1,20 @@
1
+ # Whitepaper: Gravito Membership Satellite (Identity Governance)
2
+ **Version:** 1.0.0 | **Author:** Gravito Engineering Team
3
+
4
+ ## 1. Abstract
5
+ Membership serves as the "Identity Anchor" managing the entire Customer Lifecycle.
6
+
7
+ ## 2. Deployment & Governance Scenarios
8
+
9
+ ### Case A: Tiered Marketing Synergy
10
+ - **Scenario**: A user completes a purchase that pushes their lifetime spend over $10,000.
11
+ - **Action**: Membership listens to the Commerce `commerce:order-placed` hook, upgrades the member to "Gold", and emits a `member:level-up` event.
12
+ - **Outcome**: The Marketing satellite automatically unlocks a 20% discount for the next visit.
13
+
14
+ ### Case B: High-Security Compliance (Single Device)
15
+ - **Scenario**: A fintech client requires that a user can only be logged in from one device at a time.
16
+ - **Action**: Membership enables the `VerifySingleDevice` middleware, comparing the incoming session ID with the `current_session_id` stored in the domain entity.
17
+ - **Outcome**: Fraudulent concurrent sessions are automatically terminated.
18
+
19
+ ---
20
+ *Gravito Framework: Putting the Member at the Center of the Galaxy.*
@@ -0,0 +1,26 @@
1
+ import { ServiceProvider, Container } from '@gravito/core';
2
+
3
+ /**
4
+ * Membership Satellite Service Provider
5
+ *
6
+ * Handles the registration and initialization of membership services.
7
+ * Optimized for Bun runtime with full i18n support.
8
+ */
9
+ declare class MembershipServiceProvider extends ServiceProvider {
10
+ /**
11
+ * Register bindings in the container
12
+ */
13
+ register(container: Container): void;
14
+ /**
15
+ * Expose migration path using Bun-native __dirname
16
+ */
17
+ getMigrationsPath(): string;
18
+ /**
19
+ * Boot the satellite
20
+ * Loads local translations into the global i18n system.
21
+ */
22
+ boot(): Promise<void>;
23
+ private buildPasskeysConfig;
24
+ }
25
+
26
+ export { MembershipServiceProvider };