@awesome-lang-auth/node 1.10.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 (262) hide show
  1. package/LICENSE +21 -0
  2. package/README.detailed.md +4059 -0
  3. package/README.md +248 -0
  4. package/dist/abstract/base-auth-strategy.abstract.d.ts +7 -0
  5. package/dist/abstract/base-auth-strategy.abstract.d.ts.map +1 -0
  6. package/dist/abstract/base-auth-strategy.abstract.js +7 -0
  7. package/dist/abstract/base-auth-strategy.abstract.js.map +1 -0
  8. package/dist/abstract/base-oauth-strategy.abstract.d.ts +27 -0
  9. package/dist/abstract/base-oauth-strategy.abstract.d.ts.map +1 -0
  10. package/dist/abstract/base-oauth-strategy.abstract.js +11 -0
  11. package/dist/abstract/base-oauth-strategy.abstract.js.map +1 -0
  12. package/dist/adapters/express.d.ts +45 -0
  13. package/dist/adapters/express.d.ts.map +1 -0
  14. package/dist/adapters/express.js +49 -0
  15. package/dist/adapters/express.js.map +1 -0
  16. package/dist/adapters/fastify.d.ts +72 -0
  17. package/dist/adapters/fastify.d.ts.map +1 -0
  18. package/dist/adapters/fastify.js +63 -0
  19. package/dist/adapters/fastify.js.map +1 -0
  20. package/dist/auth-configurator.d.ts +65 -0
  21. package/dist/auth-configurator.d.ts.map +1 -0
  22. package/dist/auth-configurator.js +127 -0
  23. package/dist/auth-configurator.js.map +1 -0
  24. package/dist/events/auth-event-bus.d.ts +68 -0
  25. package/dist/events/auth-event-bus.d.ts.map +1 -0
  26. package/dist/events/auth-event-bus.js +60 -0
  27. package/dist/events/auth-event-bus.js.map +1 -0
  28. package/dist/events/auth-event-names.d.ts +34 -0
  29. package/dist/events/auth-event-names.d.ts.map +1 -0
  30. package/dist/events/auth-event-names.js +41 -0
  31. package/dist/events/auth-event-names.js.map +1 -0
  32. package/dist/http-types.d.ts +135 -0
  33. package/dist/http-types.d.ts.map +1 -0
  34. package/dist/http-types.js +18 -0
  35. package/dist/http-types.js.map +1 -0
  36. package/dist/index.d.ts +80 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +88 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/interfaces/api-key-store.interface.d.ts +94 -0
  41. package/dist/interfaces/api-key-store.interface.d.ts.map +1 -0
  42. package/dist/interfaces/api-key-store.interface.js +3 -0
  43. package/dist/interfaces/api-key-store.interface.js.map +1 -0
  44. package/dist/interfaces/auth-strategy.interface.d.ts +6 -0
  45. package/dist/interfaces/auth-strategy.interface.d.ts.map +1 -0
  46. package/dist/interfaces/auth-strategy.interface.js +3 -0
  47. package/dist/interfaces/auth-strategy.interface.js.map +1 -0
  48. package/dist/interfaces/linked-accounts-store.interface.d.ts +74 -0
  49. package/dist/interfaces/linked-accounts-store.interface.d.ts.map +1 -0
  50. package/dist/interfaces/linked-accounts-store.interface.js +3 -0
  51. package/dist/interfaces/linked-accounts-store.interface.js.map +1 -0
  52. package/dist/interfaces/pending-link-store.interface.d.ts +77 -0
  53. package/dist/interfaces/pending-link-store.interface.d.ts.map +1 -0
  54. package/dist/interfaces/pending-link-store.interface.js +3 -0
  55. package/dist/interfaces/pending-link-store.interface.js.map +1 -0
  56. package/dist/interfaces/roles-permissions-store.interface.d.ts +129 -0
  57. package/dist/interfaces/roles-permissions-store.interface.d.ts.map +1 -0
  58. package/dist/interfaces/roles-permissions-store.interface.js +3 -0
  59. package/dist/interfaces/roles-permissions-store.interface.js.map +1 -0
  60. package/dist/interfaces/session-store.interface.d.ts +92 -0
  61. package/dist/interfaces/session-store.interface.d.ts.map +1 -0
  62. package/dist/interfaces/session-store.interface.js +3 -0
  63. package/dist/interfaces/session-store.interface.js.map +1 -0
  64. package/dist/interfaces/settings-store.interface.d.ts +91 -0
  65. package/dist/interfaces/settings-store.interface.d.ts.map +1 -0
  66. package/dist/interfaces/settings-store.interface.js +3 -0
  67. package/dist/interfaces/settings-store.interface.js.map +1 -0
  68. package/dist/interfaces/sse-distributor.interface.d.ts +25 -0
  69. package/dist/interfaces/sse-distributor.interface.d.ts.map +1 -0
  70. package/dist/interfaces/sse-distributor.interface.js +3 -0
  71. package/dist/interfaces/sse-distributor.interface.js.map +1 -0
  72. package/dist/interfaces/telemetry-store.interface.d.ts +72 -0
  73. package/dist/interfaces/telemetry-store.interface.d.ts.map +1 -0
  74. package/dist/interfaces/telemetry-store.interface.js +3 -0
  75. package/dist/interfaces/telemetry-store.interface.js.map +1 -0
  76. package/dist/interfaces/template-store.interface.d.ts +37 -0
  77. package/dist/interfaces/template-store.interface.d.ts.map +1 -0
  78. package/dist/interfaces/template-store.interface.js +3 -0
  79. package/dist/interfaces/template-store.interface.js.map +1 -0
  80. package/dist/interfaces/tenant-store.interface.d.ts +97 -0
  81. package/dist/interfaces/tenant-store.interface.d.ts.map +1 -0
  82. package/dist/interfaces/tenant-store.interface.js +3 -0
  83. package/dist/interfaces/tenant-store.interface.js.map +1 -0
  84. package/dist/interfaces/token-store.interface.d.ts +10 -0
  85. package/dist/interfaces/token-store.interface.d.ts.map +1 -0
  86. package/dist/interfaces/token-store.interface.js +3 -0
  87. package/dist/interfaces/token-store.interface.js.map +1 -0
  88. package/dist/interfaces/user-metadata-store.interface.d.ts +50 -0
  89. package/dist/interfaces/user-metadata-store.interface.d.ts.map +1 -0
  90. package/dist/interfaces/user-metadata-store.interface.js +3 -0
  91. package/dist/interfaces/user-metadata-store.interface.js.map +1 -0
  92. package/dist/interfaces/user-store.interface.d.ts +113 -0
  93. package/dist/interfaces/user-store.interface.d.ts.map +1 -0
  94. package/dist/interfaces/user-store.interface.js +3 -0
  95. package/dist/interfaces/user-store.interface.js.map +1 -0
  96. package/dist/interfaces/webhook-store.interface.d.ts +139 -0
  97. package/dist/interfaces/webhook-store.interface.d.ts.map +1 -0
  98. package/dist/interfaces/webhook-store.interface.js +3 -0
  99. package/dist/interfaces/webhook-store.interface.js.map +1 -0
  100. package/dist/middleware/api-key.middleware.d.ts +35 -0
  101. package/dist/middleware/api-key.middleware.d.ts.map +1 -0
  102. package/dist/middleware/api-key.middleware.js +45 -0
  103. package/dist/middleware/api-key.middleware.js.map +1 -0
  104. package/dist/middleware/auth.middleware.d.ts +13 -0
  105. package/dist/middleware/auth.middleware.d.ts.map +1 -0
  106. package/dist/middleware/auth.middleware.js +55 -0
  107. package/dist/middleware/auth.middleware.js.map +1 -0
  108. package/dist/middleware/jwks-auth.middleware.d.ts +18 -0
  109. package/dist/middleware/jwks-auth.middleware.d.ts.map +1 -0
  110. package/dist/middleware/jwks-auth.middleware.js +77 -0
  111. package/dist/middleware/jwks-auth.middleware.js.map +1 -0
  112. package/dist/models/api-key.model.d.ts +66 -0
  113. package/dist/models/api-key.model.d.ts.map +1 -0
  114. package/dist/models/api-key.model.js +3 -0
  115. package/dist/models/api-key.model.js.map +1 -0
  116. package/dist/models/auth-config.model.d.ts +387 -0
  117. package/dist/models/auth-config.model.d.ts.map +1 -0
  118. package/dist/models/auth-config.model.js +3 -0
  119. package/dist/models/auth-config.model.js.map +1 -0
  120. package/dist/models/errors.d.ts +7 -0
  121. package/dist/models/errors.d.ts.map +1 -0
  122. package/dist/models/errors.js +14 -0
  123. package/dist/models/errors.js.map +1 -0
  124. package/dist/models/session.model.d.ts +28 -0
  125. package/dist/models/session.model.d.ts.map +1 -0
  126. package/dist/models/session.model.js +3 -0
  127. package/dist/models/session.model.js.map +1 -0
  128. package/dist/models/tenant.model.d.ts +20 -0
  129. package/dist/models/tenant.model.d.ts.map +1 -0
  130. package/dist/models/tenant.model.js +3 -0
  131. package/dist/models/tenant.model.js.map +1 -0
  132. package/dist/models/token.model.d.ts +21 -0
  133. package/dist/models/token.model.d.ts.map +1 -0
  134. package/dist/models/token.model.js +3 -0
  135. package/dist/models/token.model.js.map +1 -0
  136. package/dist/models/user.model.d.ts +92 -0
  137. package/dist/models/user.model.d.ts.map +1 -0
  138. package/dist/models/user.model.js +3 -0
  139. package/dist/models/user.model.js.map +1 -0
  140. package/dist/router/admin.router.d.ts +188 -0
  141. package/dist/router/admin.router.d.ts.map +1 -0
  142. package/dist/router/admin.router.js +1507 -0
  143. package/dist/router/admin.router.js.map +1 -0
  144. package/dist/router/auth.router.d.ts +199 -0
  145. package/dist/router/auth.router.d.ts.map +1 -0
  146. package/dist/router/auth.router.js +1636 -0
  147. package/dist/router/auth.router.js.map +1 -0
  148. package/dist/router/openapi.d.ts +98 -0
  149. package/dist/router/openapi.d.ts.map +1 -0
  150. package/dist/router/openapi.js +1518 -0
  151. package/dist/router/openapi.js.map +1 -0
  152. package/dist/router/router-events.d.ts +38 -0
  153. package/dist/router/router-events.d.ts.map +1 -0
  154. package/dist/router/router-events.js +74 -0
  155. package/dist/router/router-events.js.map +1 -0
  156. package/dist/router/tools.router.d.ts +104 -0
  157. package/dist/router/tools.router.d.ts.map +1 -0
  158. package/dist/router/tools.router.js +227 -0
  159. package/dist/router/tools.router.js.map +1 -0
  160. package/dist/router/ui.router.d.ts +49 -0
  161. package/dist/router/ui.router.d.ts.map +1 -0
  162. package/dist/router/ui.router.js +272 -0
  163. package/dist/router/ui.router.js.map +1 -0
  164. package/dist/services/api-key.service.d.ts +53 -0
  165. package/dist/services/api-key.service.d.ts.map +1 -0
  166. package/dist/services/api-key.service.js +66 -0
  167. package/dist/services/api-key.service.js.map +1 -0
  168. package/dist/services/jwks.service.d.ts +73 -0
  169. package/dist/services/jwks.service.d.ts.map +1 -0
  170. package/dist/services/jwks.service.js +174 -0
  171. package/dist/services/jwks.service.js.map +1 -0
  172. package/dist/services/mailer.service.d.ts +30 -0
  173. package/dist/services/mailer.service.d.ts.map +1 -0
  174. package/dist/services/mailer.service.js +248 -0
  175. package/dist/services/mailer.service.js.map +1 -0
  176. package/dist/services/notification.service.d.ts +110 -0
  177. package/dist/services/notification.service.d.ts.map +1 -0
  178. package/dist/services/notification.service.js +79 -0
  179. package/dist/services/notification.service.js.map +1 -0
  180. package/dist/services/password.service.d.ts +5 -0
  181. package/dist/services/password.service.d.ts.map +1 -0
  182. package/dist/services/password.service.js +17 -0
  183. package/dist/services/password.service.js.map +1 -0
  184. package/dist/services/sms.service.d.ts +14 -0
  185. package/dist/services/sms.service.d.ts.map +1 -0
  186. package/dist/services/sms.service.js +51 -0
  187. package/dist/services/sms.service.js.map +1 -0
  188. package/dist/services/token.service.d.ts +62 -0
  189. package/dist/services/token.service.d.ts.map +1 -0
  190. package/dist/services/token.service.js +354 -0
  191. package/dist/services/token.service.js.map +1 -0
  192. package/dist/stores/memory-template.store.d.ts +12 -0
  193. package/dist/stores/memory-template.store.d.ts.map +1 -0
  194. package/dist/stores/memory-template.store.js +35 -0
  195. package/dist/stores/memory-template.store.js.map +1 -0
  196. package/dist/strategies/api-key/api-key.strategy.d.ts +72 -0
  197. package/dist/strategies/api-key/api-key.strategy.d.ts.map +1 -0
  198. package/dist/strategies/api-key/api-key.strategy.js +182 -0
  199. package/dist/strategies/api-key/api-key.strategy.js.map +1 -0
  200. package/dist/strategies/local/local.strategy.d.ts +19 -0
  201. package/dist/strategies/local/local.strategy.d.ts.map +1 -0
  202. package/dist/strategies/local/local.strategy.js +45 -0
  203. package/dist/strategies/local/local.strategy.js.map +1 -0
  204. package/dist/strategies/magic-link/magic-link.strategy.d.ts +8 -0
  205. package/dist/strategies/magic-link/magic-link.strategy.d.ts.map +1 -0
  206. package/dist/strategies/magic-link/magic-link.strategy.js +53 -0
  207. package/dist/strategies/magic-link/magic-link.strategy.js.map +1 -0
  208. package/dist/strategies/oauth/generic-oauth.strategy.d.ts +120 -0
  209. package/dist/strategies/oauth/generic-oauth.strategy.d.ts.map +1 -0
  210. package/dist/strategies/oauth/generic-oauth.strategy.js +88 -0
  211. package/dist/strategies/oauth/generic-oauth.strategy.js.map +1 -0
  212. package/dist/strategies/oauth/github.strategy.d.ts +31 -0
  213. package/dist/strategies/oauth/github.strategy.d.ts.map +1 -0
  214. package/dist/strategies/oauth/github.strategy.js +72 -0
  215. package/dist/strategies/oauth/github.strategy.js.map +1 -0
  216. package/dist/strategies/oauth/google.strategy.d.ts +31 -0
  217. package/dist/strategies/oauth/google.strategy.d.ts.map +1 -0
  218. package/dist/strategies/oauth/google.strategy.js +61 -0
  219. package/dist/strategies/oauth/google.strategy.js.map +1 -0
  220. package/dist/strategies/sms/sms.strategy.d.ts +7 -0
  221. package/dist/strategies/sms/sms.strategy.d.ts.map +1 -0
  222. package/dist/strategies/sms/sms.strategy.js +39 -0
  223. package/dist/strategies/sms/sms.strategy.js.map +1 -0
  224. package/dist/strategies/two-factor/totp.strategy.d.ts +12 -0
  225. package/dist/strategies/two-factor/totp.strategy.d.ts.map +1 -0
  226. package/dist/strategies/two-factor/totp.strategy.js +32 -0
  227. package/dist/strategies/two-factor/totp.strategy.js.map +1 -0
  228. package/dist/tools/auth-tools.d.ts +200 -0
  229. package/dist/tools/auth-tools.d.ts.map +1 -0
  230. package/dist/tools/auth-tools.js +232 -0
  231. package/dist/tools/auth-tools.js.map +1 -0
  232. package/dist/tools/sse-manager.d.ts +118 -0
  233. package/dist/tools/sse-manager.d.ts.map +1 -0
  234. package/dist/tools/sse-manager.js +163 -0
  235. package/dist/tools/sse-manager.js.map +1 -0
  236. package/dist/tools/sse-notify.decorator.d.ts +74 -0
  237. package/dist/tools/sse-notify.decorator.d.ts.map +1 -0
  238. package/dist/tools/sse-notify.decorator.js +78 -0
  239. package/dist/tools/sse-notify.decorator.js.map +1 -0
  240. package/dist/tools/webhook-action.d.ts +130 -0
  241. package/dist/tools/webhook-action.d.ts.map +1 -0
  242. package/dist/tools/webhook-action.js +144 -0
  243. package/dist/tools/webhook-action.js.map +1 -0
  244. package/dist/tools/webhook-sender.d.ts +31 -0
  245. package/dist/tools/webhook-sender.d.ts.map +1 -0
  246. package/dist/tools/webhook-sender.js +80 -0
  247. package/dist/tools/webhook-sender.js.map +1 -0
  248. package/dist/ui-assets/2fa.html +115 -0
  249. package/dist/ui-assets/account-conflict.html +108 -0
  250. package/dist/ui-assets/admin.css +263 -0
  251. package/dist/ui-assets/admin.js +1927 -0
  252. package/dist/ui-assets/auth.js +725 -0
  253. package/dist/ui-assets/base.css +219 -0
  254. package/dist/ui-assets/forgot-password.html +93 -0
  255. package/dist/ui-assets/link-verify.html +74 -0
  256. package/dist/ui-assets/login.html +135 -0
  257. package/dist/ui-assets/magic-link.html +112 -0
  258. package/dist/ui-assets/register.html +122 -0
  259. package/dist/ui-assets/reset-password.html +103 -0
  260. package/dist/ui-assets/ui-i18n-keys.json +78 -0
  261. package/dist/ui-assets/verify-email.html +66 -0
  262. package/package.json +89 -0
@@ -0,0 +1,219 @@
1
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
2
+
3
+ :root {
4
+ --primary-color: #4a90d9;
5
+ --primary-color-hover: #357abd;
6
+ --secondary-color: #6c757d;
7
+ --secondary-color-hover: #5a6268;
8
+ --bg-color: #f8fafc;
9
+ --bg-image: none;
10
+ --card-bg: #ffffff;
11
+ --text-color: #1e293b;
12
+ --text-muted: #64748b;
13
+ --error-color: #ef4444;
14
+ --success-color: #22c55e;
15
+ --border-color: #e2e8f0;
16
+ --input-focus: #4a90d9;
17
+ }
18
+
19
+ * {
20
+ box-sizing: border-box;
21
+ margin: 0;
22
+ padding: 0;
23
+ }
24
+
25
+ body {
26
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
27
+ background-color: var(--bg-color);
28
+ background-image: var(--bg-image);
29
+ background-size: cover;
30
+ background-position: center;
31
+ background-attachment: fixed;
32
+ color: var(--text-color);
33
+ display: flex;
34
+ justify-content: center;
35
+ align-items: center;
36
+ min-height: 100vh;
37
+ padding: 20px;
38
+ }
39
+
40
+ .auth-container {
41
+ width: 100%;
42
+ max-width: 400px;
43
+ background: var(--card-bg);
44
+ border: 1px solid var(--border-color);
45
+ border-radius: 12px;
46
+ padding: 32px;
47
+ box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
48
+ }
49
+
50
+ .logo {
51
+ display: block;
52
+ height: 48px;
53
+ width: auto;
54
+ margin: 0 auto 16px;
55
+ }
56
+
57
+ h1 {
58
+ font-size: 24px;
59
+ font-weight: 700;
60
+ text-align: center;
61
+ color: var(--primary-color);
62
+ margin-bottom: 4px;
63
+ }
64
+
65
+ h2 {
66
+ font-size: 18px;
67
+ font-weight: 400;
68
+ text-align: center;
69
+ color: var(--text-muted);
70
+ margin-bottom: 24px;
71
+ }
72
+
73
+ .alert {
74
+ padding: 12px;
75
+ border-radius: 6px;
76
+ font-size: 14px;
77
+ margin-bottom: 16px;
78
+ border: 1px solid transparent;
79
+ }
80
+
81
+ .alert-error {
82
+ background-color: #fef2f2;
83
+ color: var(--error-color);
84
+ border-color: #fee2e2;
85
+ }
86
+
87
+ .alert-success {
88
+ background-color: #f0fdf4;
89
+ color: var(--success-color);
90
+ border-color: #dcfce7;
91
+ }
92
+
93
+ form {
94
+ display: flex;
95
+ flex-direction: column;
96
+ gap: 16px;
97
+ }
98
+
99
+ .form-group {
100
+ display: flex;
101
+ flex-direction: column;
102
+ gap: 4px;
103
+ }
104
+
105
+ label {
106
+ font-size: 14px;
107
+ font-weight: 600;
108
+ color: #374151;
109
+ }
110
+
111
+ input {
112
+ width: 100%;
113
+ padding: 8px 12px;
114
+ border: 1px solid #d1d5db;
115
+ border-radius: 6px;
116
+ font-size: 14px;
117
+ transition: border-color 0.2s;
118
+ }
119
+
120
+ input:focus {
121
+ outline: none;
122
+ border-color: var(--input-focus);
123
+ box-shadow: 0 0 0 3px rgba(74, 144, 217, 0.1);
124
+ }
125
+
126
+ button {
127
+ width: 100%;
128
+ padding: 12px;
129
+ border: none;
130
+ border-radius: 6px;
131
+ font-size: 14px;
132
+ font-weight: 600;
133
+ cursor: pointer;
134
+ transition: background-color 0.2s, opacity 0.2s;
135
+ }
136
+
137
+ button[type="submit"] {
138
+ background-color: var(--primary-color);
139
+ color: white;
140
+ }
141
+
142
+ button[type="submit"]:hover {
143
+ background-color: var(--primary-color-hover);
144
+ }
145
+
146
+ button:disabled {
147
+ opacity: 0.6;
148
+ cursor: not-allowed;
149
+ }
150
+
151
+ .divider {
152
+ position: relative;
153
+ margin: 24px 0;
154
+ border-top: 1px solid var(--border-color);
155
+ }
156
+
157
+ .divider span {
158
+ position: absolute;
159
+ top: 50%;
160
+ left: 50%;
161
+ transform: translate(-50%, -50%);
162
+ background: var(--card-bg);
163
+ padding: 0 8px;
164
+ font-size: 10px;
165
+ color: #9ca3af;
166
+ font-weight: 600;
167
+ text-transform: uppercase;
168
+ letter-spacing: 0.05em;
169
+ }
170
+
171
+ .social-buttons {
172
+ display: flex;
173
+ flex-direction: column;
174
+ gap: 12px;
175
+ }
176
+
177
+ .btn-social {
178
+ display: flex;
179
+ align-items: center;
180
+ justify-content: center;
181
+ gap: 8px;
182
+ background-color: white;
183
+ border: 1px solid var(--secondary-color);
184
+ color: var(--secondary-color);
185
+ text-decoration: none;
186
+ padding: 10px;
187
+ }
188
+
189
+ .btn-social:hover {
190
+ background-color: #f9fafb;
191
+ border-color: var(--secondary-color-hover);
192
+ color: var(--secondary-color-hover);
193
+ }
194
+
195
+ .icon {
196
+ width: 16px;
197
+ height: 16px;
198
+ }
199
+
200
+ .footer-links {
201
+ margin-top: 24px;
202
+ text-align: center;
203
+ font-size: 14px;
204
+ color: var(--text-muted);
205
+ }
206
+
207
+ .footer-links a {
208
+ color: var(--primary-color);
209
+ text-decoration: none;
210
+ font-weight: 600;
211
+ }
212
+
213
+ .footer-links a:hover {
214
+ text-decoration: underline;
215
+ }
216
+
217
+ .hidden {
218
+ display: none !important;
219
+ }
@@ -0,0 +1,93 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Forgot Password - Awesome Node Auth</title>
8
+ <link rel="stylesheet" href="base.css">
9
+ </head>
10
+
11
+ <body>
12
+ <div class="auth-container">
13
+ <img src="" alt="Logo" class="logo hidden">
14
+ <h1 class="site-name" data-i18n="site_name">Awesome Node Auth</h1>
15
+ <h2 data-i18n="forgot_password_title">Forgot Password</h2>
16
+
17
+ <div id="alert" class="alert hidden"></div>
18
+
19
+ <div id="request-form-container">
20
+ <p class="footer-links" style="margin-bottom: 20px; text-align: left;" data-i18n="forgot_password_instruction">
21
+ Enter your email address and we'll send you a link to reset your password.
22
+ </p>
23
+ <form id="forgot-form">
24
+ <div class="form-group">
25
+ <label for="email" data-i18n="email_label">Email</label>
26
+ <input type="email" id="email" name="email" required data-i18n="email_placeholder">
27
+ </div>
28
+ <button type="submit" id="submit-btn" data-i18n="send_reset_link_button">Send Reset Link</button>
29
+ </form>
30
+ </div>
31
+
32
+ <div id="success-message" class="hidden">
33
+ <div class="alert alert-success" data-i18n="forgot_password_success">
34
+ If an account exists for <strong id="sent-email"></strong>, you will receive a password reset link
35
+ shortly.
36
+ </div>
37
+ <p class="footer-links">
38
+ <a href="login" data-i18n="return_to_login_link">Return to login</a>
39
+ </p>
40
+ </div>
41
+
42
+ <div class="footer-links" id="login-link">
43
+ <p><span data-i18n="remember_password_text">Remember your password?</span> <a href="login" data-i18n="login_link">Login</a></p>
44
+ </div>
45
+ </div>
46
+
47
+ <script src="auth.js?v=2"></script>
48
+ <script>
49
+ document.addEventListener('DOMContentLoaded', async () => {
50
+ await AuthService.init();
51
+
52
+ const form = document.getElementById('forgot-form');
53
+ const alert = document.getElementById('alert');
54
+ const submitBtn = document.getElementById('submit-btn');
55
+ const requestContainer = document.getElementById('request-form-container');
56
+ const successContainer = document.getElementById('success-message');
57
+ const loginLink = document.getElementById('login-link');
58
+
59
+ form.addEventListener('submit', async (e) => {
60
+ e.preventDefault();
61
+ alert.className = 'alert hidden';
62
+ submitBtn.disabled = true;
63
+ submitBtn.textContent = 'Sending...';
64
+
65
+ const email = form.email.value;
66
+
67
+ try {
68
+ const result = await AuthService.apiCall('/forgot-password', 'POST', { email });
69
+
70
+ if (result.success) {
71
+ document.getElementById('sent-email').textContent = email;
72
+ requestContainer.classList.add('hidden');
73
+ loginLink.classList.add('hidden');
74
+ successContainer.classList.remove('hidden');
75
+ } else {
76
+ alert.textContent = result.error || 'Request failed';
77
+ alert.classList.add('alert-error');
78
+ alert.classList.remove('hidden');
79
+ }
80
+ } catch (err) {
81
+ alert.textContent = 'An unexpected error occurred';
82
+ alert.classList.add('alert-error');
83
+ alert.classList.remove('hidden');
84
+ } finally {
85
+ submitBtn.disabled = false;
86
+ submitBtn.textContent = 'Send Reset Link';
87
+ }
88
+ });
89
+ });
90
+ </script>
91
+ </body>
92
+
93
+ </html>
@@ -0,0 +1,74 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Linking Account - Awesome Node Auth</title>
8
+ <link rel="stylesheet" href="base.css">
9
+ </head>
10
+
11
+ <body>
12
+ <div class="auth-container">
13
+ <img src="" alt="Logo" class="logo hidden">
14
+ <h1 class="site-name" data-i18n="site_name">Awesome Node Auth</h1>
15
+ <h2 data-i18n="account_linking_title">Account Linking</h2>
16
+
17
+ <div id="alert" class="alert hidden"></div>
18
+
19
+ <div id="loading" class="footer-links" data-i18n="account_linking_loading">
20
+ Completing account linking, please wait…
21
+ </div>
22
+
23
+ <div id="footer" class="footer-links hidden">
24
+ <a href="login" data-i18n="go_to_login_link">Go to login</a>
25
+ </div>
26
+ </div>
27
+
28
+ <script src="auth.js?v=2"></script>
29
+ <script>
30
+ document.addEventListener('DOMContentLoaded', async () => {
31
+ await AuthService.init();
32
+
33
+ const params = new URLSearchParams(window.location.search);
34
+ const token = params.get('token');
35
+ const alertEl = document.getElementById('alert');
36
+ const loading = document.getElementById('loading');
37
+ const footer = document.getElementById('footer');
38
+
39
+ function showResult(msg, isError) {
40
+ loading.classList.add('hidden');
41
+ footer.classList.remove('hidden');
42
+ alertEl.textContent = msg;
43
+ alertEl.className = 'alert ' + (isError ? 'alert-error' : 'alert-success');
44
+ }
45
+
46
+ if (!token) {
47
+ showResult('Invalid or missing link token.', true);
48
+ return;
49
+ }
50
+
51
+ try {
52
+ // POST /link-verify — completes the account link and optionally logs in
53
+ const result = await AuthService.apiCall('/link-verify', 'POST', {
54
+ token,
55
+ loginAfterLinking: true,
56
+ });
57
+
58
+ if (result.success) {
59
+ showResult('Your account has been linked successfully! Redirecting…', false);
60
+ setTimeout(() => {
61
+ // If tokens were returned (loginAfterLinking), redirect to home
62
+ window.location.href = '../..';
63
+ }, 1500);
64
+ } else {
65
+ showResult(result.error || 'Account linking failed.', true);
66
+ }
67
+ } catch (err) {
68
+ showResult(err.message || 'An unexpected error occurred.', true);
69
+ }
70
+ });
71
+ </script>
72
+ </body>
73
+
74
+ </html>
@@ -0,0 +1,135 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Login - Awesome Node Auth</title>
8
+ <link rel="stylesheet" href="base.css">
9
+ </head>
10
+
11
+ <body>
12
+ <div class="auth-container">
13
+ <img src="" alt="Logo" class="logo hidden">
14
+ <h1 class="site-name" data-i18n="site_name">Awesome Node Auth</h1>
15
+ <h2 data-i18n="login_title">Login</h2>
16
+
17
+ <div id="alert" class="alert alert-error hidden"></div>
18
+
19
+ <form id="login-form">
20
+ <div class="form-group">
21
+ <label for="email" data-i18n="email_label">Email</label>
22
+ <input type="email" id="email" name="email" required data-i18n="email_placeholder">
23
+ </div>
24
+ <div class="form-group">
25
+ <label for="password" data-i18n="password_label">Password</label>
26
+ <input type="password" id="password" name="password" required data-i18n="password_placeholder">
27
+ </div>
28
+ <button type="submit" id="submit-btn" data-i18n="login_button">Login</button>
29
+ </form>
30
+
31
+ <div id="social-section" class="hidden">
32
+ <div class="divider">
33
+ <span data-i18n="social_divider">Or continue with</span>
34
+ </div>
35
+ <div class="social-buttons">
36
+ <a href="../oauth/google" class="btn-social hidden" data-feature="google">
37
+ <svg class="icon" viewBox="0 0 24 24">
38
+ <path
39
+ d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
40
+ fill="#4285F4" />
41
+ <path
42
+ d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
43
+ fill="#34A853" />
44
+ <path
45
+ d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
46
+ fill="#FBBC05" />
47
+ <path
48
+ d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
49
+ fill="#EA4335" />
50
+ </svg>
51
+ Google
52
+ </a>
53
+ <a href="../oauth/github" class="btn-social hidden" data-feature="github">
54
+ <svg class="icon" fill="currentColor" viewBox="0 0 24 24">
55
+ <path fill-rule="evenodd"
56
+ d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"
57
+ clip-rule="evenodd"></path>
58
+ </svg>
59
+ GitHub
60
+ </a>
61
+ </div>
62
+
63
+ </div>
64
+
65
+ <div class="footer-links">
66
+ <p data-feature="forgot-password" class="hidden"><a href="forgot-password" data-i18n="forgot_password_link">Forgot password?</a></p>
67
+ <p data-feature="register" class="hidden"><span data-i18n="no_account_text">Don't have an account?</span> <a href="register" data-i18n="signup_link">Sign up</a></p>
68
+ </div>
69
+
70
+ <script src="auth.js?v=2"></script>
71
+ <script>
72
+ document.addEventListener('DOMContentLoaded', async () => {
73
+ await AuthService.init();
74
+
75
+ // Redirect if already authenticated
76
+ if (AuthService.user) {
77
+ window.location.href = '/';
78
+ return;
79
+ }
80
+
81
+ // Show social section if at least one provider is enabled
82
+ if (AuthService.config.features.google || AuthService.config.features.github) {
83
+ document.getElementById('social-section').classList.remove('hidden');
84
+ if (AuthService.config.features.google) document.querySelector('[data-feature="google"]').classList.remove('hidden');
85
+ if (AuthService.config.features.github) document.querySelector('[data-feature="github"]').classList.remove('hidden');
86
+ }
87
+
88
+ if (AuthService.config.features.register) {
89
+ document.querySelector('[data-feature="register"]')?.classList.remove('hidden');
90
+ }
91
+
92
+ if (AuthService.config.features.forgotPassword) {
93
+ document.querySelector('[data-feature="forgot-password"]')?.classList.remove('hidden');
94
+ }
95
+
96
+ const form = document.getElementById('login-form');
97
+ const alert = document.getElementById('alert');
98
+ const submitBtn = document.getElementById('submit-btn');
99
+
100
+ form.addEventListener('submit', async (e) => {
101
+ e.preventDefault();
102
+ alert.classList.add('hidden');
103
+ submitBtn.disabled = true;
104
+ submitBtn.textContent = 'Logging in...';
105
+
106
+ const email = form.email.value;
107
+ const password = form.password.value;
108
+
109
+ try {
110
+ const result = await AuthService.apiCall('/login', 'POST', { email, password });
111
+
112
+ if (result.success || result.requiresTwoFactor) {
113
+ if (result.requiresTwoFactor) {
114
+ // Redirect to 2FA page or show setup
115
+ window.location.href = `2fa?token=${result.tempToken}`;
116
+ } else {
117
+ window.location.href = '/';
118
+ }
119
+ } else {
120
+ alert.textContent = result.error || 'Login failed';
121
+ alert.classList.remove('hidden');
122
+ }
123
+ } catch (err) {
124
+ alert.textContent = 'An unexpected error occurred';
125
+ alert.classList.remove('hidden');
126
+ } finally {
127
+ submitBtn.disabled = false;
128
+ submitBtn.textContent = 'Login';
129
+ }
130
+ });
131
+ });
132
+ </script>
133
+ </body>
134
+
135
+ </html>
@@ -0,0 +1,112 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Magic Link - Awesome Node Auth</title>
8
+ <link rel="stylesheet" href="base.css">
9
+ </head>
10
+
11
+ <body>
12
+ <div class="auth-container">
13
+ <img src="" alt="Logo" class="logo hidden">
14
+ <h1 class="site-name" data-i18n="site_name">Awesome Node Auth</h1>
15
+ <h2 data-i18n="magic_link_title">Magic Link</h2>
16
+
17
+ <div id="alert" class="alert hidden"></div>
18
+
19
+ <form id="magic-link-form">
20
+ <p class="footer-links" style="margin-bottom: 20px; text-align: left;" data-i18n="magic_link_instruction">
21
+ Enter your email and we'll send you a magic link to sign in instantly.
22
+ </p>
23
+ <div class="form-group">
24
+ <label for="email" data-i18n="email_label">Email</label>
25
+ <input type="email" id="email" name="email" required data-i18n="email_placeholder">
26
+ </div>
27
+ <button type="submit" id="submit-btn" data-feature="magicLink" data-i18n="send_magic_link_button">Send Magic Link</button>
28
+ </form>
29
+
30
+ <div id="success-message" class="hidden">
31
+ <div class="alert alert-success">
32
+ A magic link has been sent to your email. Check your inbox and click the link to log in.
33
+ </div>
34
+ </div>
35
+
36
+ <div class="footer-links">
37
+ <a href="login">Back to login</a>
38
+ </div>
39
+ </div>
40
+
41
+ <script src="auth.js?v=2"></script>
42
+ <script>
43
+ document.addEventListener('DOMContentLoaded', async () => {
44
+ await AuthService.init();
45
+
46
+ const urlParams = new URLSearchParams(window.location.search);
47
+ const token = urlParams.get('token');
48
+ const alert = document.getElementById('alert');
49
+ const form = document.getElementById('magic-link-form');
50
+ const successMsg = document.getElementById('success-message');
51
+
52
+ // If token in URL, verify it automatically
53
+ if (token) {
54
+ form.classList.add('hidden');
55
+ document.querySelector('h2').textContent = 'Verifying Magic Link';
56
+ alert.textContent = 'Verifying your link, please wait...';
57
+ alert.className = 'alert';
58
+ alert.classList.remove('hidden');
59
+
60
+ try {
61
+ const result = await AuthService.apiCall('/magic-link/verify', 'POST', { token });
62
+ if (result.success) {
63
+ alert.textContent = 'Successfully logged in! Redirecting...';
64
+ alert.className = 'alert alert-success';
65
+ setTimeout(() => window.location.href = '/', 1500);
66
+ } else {
67
+ alert.textContent = result.error || 'Invalid or expired magic link';
68
+ alert.className = 'alert alert-error';
69
+ }
70
+ } catch (err) {
71
+ alert.textContent = 'An unexpected error occurred';
72
+ alert.className = 'alert alert-error';
73
+ }
74
+ return;
75
+ }
76
+
77
+ // Otherwise show request form
78
+ form.addEventListener('submit', async (e) => {
79
+ e.preventDefault();
80
+ alert.className = 'alert hidden';
81
+ const submitBtn = document.getElementById('submit-btn');
82
+ submitBtn.disabled = true;
83
+ submitBtn.textContent = 'Sending...';
84
+
85
+ try {
86
+ const result = await AuthService.apiCall('/magic-link/send', 'POST', {
87
+ email: form.email.value,
88
+ mode: 'login'
89
+ });
90
+
91
+ if (result.success) {
92
+ form.classList.add('hidden');
93
+ successMsg.classList.remove('hidden');
94
+ } else {
95
+ alert.textContent = result.error || 'Failed to send magic link';
96
+ alert.className = 'alert alert-error';
97
+ alert.classList.remove('hidden');
98
+ }
99
+ } catch (err) {
100
+ alert.textContent = 'An unexpected error occurred';
101
+ alert.className = 'alert alert-error';
102
+ alert.classList.remove('hidden');
103
+ } finally {
104
+ submitBtn.disabled = false;
105
+ submitBtn.textContent = 'Send Magic Link';
106
+ }
107
+ });
108
+ });
109
+ </script>
110
+ </body>
111
+
112
+ </html>