@techelusive/nest-auth 0.0.0-stage → 0.2.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 (340) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/LICENSE +21 -0
  3. package/README.md +204 -2
  4. package/api/openapi.json +4399 -0
  5. package/api/techelusive-authentication.postman_collection.json +3178 -0
  6. package/dist/auth-options.d.ts +156 -0
  7. package/dist/auth-options.js +3 -0
  8. package/dist/auth-options.js.map +1 -0
  9. package/dist/auth-options.validation.d.ts +9 -0
  10. package/dist/auth-options.validation.js +74 -0
  11. package/dist/auth-options.validation.js.map +1 -0
  12. package/dist/auth.module.d.ts +38 -0
  13. package/dist/auth.module.js +173 -0
  14. package/dist/auth.module.js.map +1 -0
  15. package/dist/common/auth-error.d.ts +16 -0
  16. package/dist/common/auth-error.js +23 -0
  17. package/dist/common/auth-error.js.map +1 -0
  18. package/dist/common/auth-exception.filter.d.ts +24 -0
  19. package/dist/common/auth-exception.filter.js +66 -0
  20. package/dist/common/auth-exception.filter.js.map +1 -0
  21. package/dist/common/crypto/jwt.d.ts +89 -0
  22. package/dist/common/crypto/jwt.js +144 -0
  23. package/dist/common/crypto/jwt.js.map +1 -0
  24. package/dist/common/crypto/random-secrets.d.ts +78 -0
  25. package/dist/common/crypto/random-secrets.js +113 -0
  26. package/dist/common/crypto/random-secrets.js.map +1 -0
  27. package/dist/common/crypto/remote-public-keys.d.ts +49 -0
  28. package/dist/common/crypto/remote-public-keys.js +105 -0
  29. package/dist/common/crypto/remote-public-keys.js.map +1 -0
  30. package/dist/common/crypto/totp.d.ts +68 -0
  31. package/dist/common/crypto/totp.js +148 -0
  32. package/dist/common/crypto/totp.js.map +1 -0
  33. package/dist/common/encryption.service.d.ts +36 -0
  34. package/dist/common/encryption.service.js +111 -0
  35. package/dist/common/encryption.service.js.map +1 -0
  36. package/dist/common/identifiers.d.ts +48 -0
  37. package/dist/common/identifiers.js +89 -0
  38. package/dist/common/identifiers.js.map +1 -0
  39. package/dist/common/network-safety.d.ts +19 -0
  40. package/dist/common/network-safety.js +72 -0
  41. package/dist/common/network-safety.js.map +1 -0
  42. package/dist/common/rate-limiter.service.d.ts +63 -0
  43. package/dist/common/rate-limiter.service.js +158 -0
  44. package/dist/common/rate-limiter.service.js.map +1 -0
  45. package/dist/common/refresh-token-cookie.d.ts +78 -0
  46. package/dist/common/refresh-token-cookie.js +185 -0
  47. package/dist/common/refresh-token-cookie.js.map +1 -0
  48. package/dist/common/request-context.d.ts +14 -0
  49. package/dist/common/request-context.js +22 -0
  50. package/dist/common/request-context.js.map +1 -0
  51. package/dist/common/strict-validation.pipe.d.ts +8 -0
  52. package/dist/common/strict-validation.pipe.js +16 -0
  53. package/dist/common/strict-validation.pipe.js.map +1 -0
  54. package/dist/common/time.d.ts +15 -0
  55. package/dist/common/time.js +34 -0
  56. package/dist/common/time.js.map +1 -0
  57. package/dist/constants.d.ts +1326 -0
  58. package/dist/constants.js +1142 -0
  59. package/dist/constants.js.map +1 -0
  60. package/dist/database/create-auth-tables.migration.d.ts +26 -0
  61. package/dist/database/create-auth-tables.migration.js +291 -0
  62. package/dist/database/create-auth-tables.migration.js.map +1 -0
  63. package/dist/database/email-change-and-retention.migration.d.ts +25 -0
  64. package/dist/database/email-change-and-retention.migration.js +54 -0
  65. package/dist/database/email-change-and-retention.migration.js.map +1 -0
  66. package/dist/database/entities/api-key.entity.d.ts +17 -0
  67. package/dist/database/entities/api-key.entity.js +80 -0
  68. package/dist/database/entities/api-key.entity.js.map +1 -0
  69. package/dist/database/entities/audit-log.entity.d.ts +13 -0
  70. package/dist/database/entities/audit-log.entity.js +64 -0
  71. package/dist/database/entities/audit-log.entity.js.map +1 -0
  72. package/dist/database/entities/backup-code.entity.d.ts +9 -0
  73. package/dist/database/entities/backup-code.entity.js +52 -0
  74. package/dist/database/entities/backup-code.entity.js.map +1 -0
  75. package/dist/database/entities/index.d.ts +43 -0
  76. package/dist/database/entities/index.js +82 -0
  77. package/dist/database/entities/index.js.map +1 -0
  78. package/dist/database/entities/json-object.d.ts +12 -0
  79. package/dist/database/entities/json-object.js +3 -0
  80. package/dist/database/entities/json-object.js.map +1 -0
  81. package/dist/database/entities/link-token.entity.d.ts +15 -0
  82. package/dist/database/entities/link-token.entity.js +64 -0
  83. package/dist/database/entities/link-token.entity.js.map +1 -0
  84. package/dist/database/entities/one-time-code.entity.d.ts +16 -0
  85. package/dist/database/entities/one-time-code.entity.js +69 -0
  86. package/dist/database/entities/one-time-code.entity.js.map +1 -0
  87. package/dist/database/entities/organization-invitation.entity.d.ts +14 -0
  88. package/dist/database/entities/organization-invitation.entity.js +73 -0
  89. package/dist/database/entities/organization-invitation.entity.js.map +1 -0
  90. package/dist/database/entities/organization-member.entity.d.ts +9 -0
  91. package/dist/database/entities/organization-member.entity.js +48 -0
  92. package/dist/database/entities/organization-member.entity.js.map +1 -0
  93. package/dist/database/entities/organization.entity.d.ts +12 -0
  94. package/dist/database/entities/organization.entity.js +58 -0
  95. package/dist/database/entities/organization.entity.js.map +1 -0
  96. package/dist/database/entities/passkey.entity.d.ts +19 -0
  97. package/dist/database/entities/passkey.entity.js +78 -0
  98. package/dist/database/entities/passkey.entity.js.map +1 -0
  99. package/dist/database/entities/password.entity.d.ts +6 -0
  100. package/dist/database/entities/password.entity.js +36 -0
  101. package/dist/database/entities/password.entity.js.map +1 -0
  102. package/dist/database/entities/refresh-token.entity.d.ts +9 -0
  103. package/dist/database/entities/refresh-token.entity.js +53 -0
  104. package/dist/database/entities/refresh-token.entity.js.map +1 -0
  105. package/dist/database/entities/session.entity.d.ts +20 -0
  106. package/dist/database/entities/session.entity.js +87 -0
  107. package/dist/database/entities/session.entity.js.map +1 -0
  108. package/dist/database/entities/settings.entity.d.ts +7 -0
  109. package/dist/database/entities/settings.entity.js +41 -0
  110. package/dist/database/entities/settings.entity.js.map +1 -0
  111. package/dist/database/entities/sign-in-challenge.entity.d.ts +23 -0
  112. package/dist/database/entities/sign-in-challenge.entity.js +80 -0
  113. package/dist/database/entities/sign-in-challenge.entity.js.map +1 -0
  114. package/dist/database/entities/signing-key.entity.d.ts +11 -0
  115. package/dist/database/entities/signing-key.entity.js +54 -0
  116. package/dist/database/entities/signing-key.entity.js.map +1 -0
  117. package/dist/database/entities/social-account.entity.d.ts +13 -0
  118. package/dist/database/entities/social-account.entity.js +54 -0
  119. package/dist/database/entities/social-account.entity.js.map +1 -0
  120. package/dist/database/entities/two-factor-secret.entity.d.ts +10 -0
  121. package/dist/database/entities/two-factor-secret.entity.js +48 -0
  122. package/dist/database/entities/two-factor-secret.entity.js.map +1 -0
  123. package/dist/database/entities/user.entity.d.ts +34 -0
  124. package/dist/database/entities/user.entity.js +129 -0
  125. package/dist/database/entities/user.entity.js.map +1 -0
  126. package/dist/database/entities/webhook-delivery.entity.d.ts +17 -0
  127. package/dist/database/entities/webhook-delivery.entity.js +79 -0
  128. package/dist/database/entities/webhook-delivery.entity.js.map +1 -0
  129. package/dist/database/entities/webhook.entity.d.ts +12 -0
  130. package/dist/database/entities/webhook.entity.js +58 -0
  131. package/dist/database/entities/webhook.entity.js.map +1 -0
  132. package/dist/database/typeorm-row.d.ts +21 -0
  133. package/dist/database/typeorm-row.js +29 -0
  134. package/dist/database/typeorm-row.js.map +1 -0
  135. package/dist/features/account/account.controller.d.ts +259 -0
  136. package/dist/features/account/account.controller.js +372 -0
  137. package/dist/features/account/account.controller.js.map +1 -0
  138. package/dist/features/account/account.dto.d.ts +16 -0
  139. package/dist/features/account/account.dto.js +61 -0
  140. package/dist/features/account/account.dto.js.map +1 -0
  141. package/dist/features/account/data-export.service.d.ts +85 -0
  142. package/dist/features/account/data-export.service.js +125 -0
  143. package/dist/features/account/data-export.service.js.map +1 -0
  144. package/dist/features/account/health.service.d.ts +30 -0
  145. package/dist/features/account/health.service.js +59 -0
  146. package/dist/features/account/health.service.js.map +1 -0
  147. package/dist/features/admin/admin.controller.d.ts +382 -0
  148. package/dist/features/admin/admin.controller.js +623 -0
  149. package/dist/features/admin/admin.controller.js.map +1 -0
  150. package/dist/features/admin/admin.dto.d.ts +61 -0
  151. package/dist/features/admin/admin.dto.js +253 -0
  152. package/dist/features/admin/admin.dto.js.map +1 -0
  153. package/dist/features/admin/admin.service.d.ts +142 -0
  154. package/dist/features/admin/admin.service.js +227 -0
  155. package/dist/features/admin/admin.service.js.map +1 -0
  156. package/dist/features/api-keys/api-keys.service.d.ts +67 -0
  157. package/dist/features/api-keys/api-keys.service.js +144 -0
  158. package/dist/features/api-keys/api-keys.service.js.map +1 -0
  159. package/dist/features/email-change/email-change.controller.d.ts +38 -0
  160. package/dist/features/email-change/email-change.controller.js +85 -0
  161. package/dist/features/email-change/email-change.controller.js.map +1 -0
  162. package/dist/features/email-change/email-change.dto.d.ts +10 -0
  163. package/dist/features/email-change/email-change.dto.js +43 -0
  164. package/dist/features/email-change/email-change.dto.js.map +1 -0
  165. package/dist/features/email-change/email-change.service.d.ts +74 -0
  166. package/dist/features/email-change/email-change.service.js +179 -0
  167. package/dist/features/email-change/email-change.service.js.map +1 -0
  168. package/dist/features/email-links/email-verification.service.d.ts +46 -0
  169. package/dist/features/email-links/email-verification.service.js +94 -0
  170. package/dist/features/email-links/email-verification.service.js.map +1 -0
  171. package/dist/features/email-links/link-tokens.service.d.ts +44 -0
  172. package/dist/features/email-links/link-tokens.service.js +122 -0
  173. package/dist/features/email-links/link-tokens.service.js.map +1 -0
  174. package/dist/features/events/auth-events.service.d.ts +52 -0
  175. package/dist/features/events/auth-events.service.js +117 -0
  176. package/dist/features/events/auth-events.service.js.map +1 -0
  177. package/dist/features/maintenance/data-retention.service.d.ts +60 -0
  178. package/dist/features/maintenance/data-retention.service.js +182 -0
  179. package/dist/features/maintenance/data-retention.service.js.map +1 -0
  180. package/dist/features/notifications/notifications.service.d.ts +40 -0
  181. package/dist/features/notifications/notifications.service.js +94 -0
  182. package/dist/features/notifications/notifications.service.js.map +1 -0
  183. package/dist/features/one-time-codes/one-time-codes.service.d.ts +40 -0
  184. package/dist/features/one-time-codes/one-time-codes.service.js +102 -0
  185. package/dist/features/one-time-codes/one-time-codes.service.js.map +1 -0
  186. package/dist/features/organizations/organizations.controller.d.ts +220 -0
  187. package/dist/features/organizations/organizations.controller.js +337 -0
  188. package/dist/features/organizations/organizations.controller.js.map +1 -0
  189. package/dist/features/organizations/organizations.dto.d.ts +31 -0
  190. package/dist/features/organizations/organizations.dto.js +100 -0
  191. package/dist/features/organizations/organizations.dto.js.map +1 -0
  192. package/dist/features/organizations/organizations.service.d.ts +274 -0
  193. package/dist/features/organizations/organizations.service.js +481 -0
  194. package/dist/features/organizations/organizations.service.js.map +1 -0
  195. package/dist/features/passkeys/passkeys.controller.d.ts +92 -0
  196. package/dist/features/passkeys/passkeys.controller.js +183 -0
  197. package/dist/features/passkeys/passkeys.controller.js.map +1 -0
  198. package/dist/features/passkeys/passkeys.dto.d.ts +13 -0
  199. package/dist/features/passkeys/passkeys.dto.js +50 -0
  200. package/dist/features/passkeys/passkeys.dto.js.map +1 -0
  201. package/dist/features/passkeys/passkeys.service.d.ts +159 -0
  202. package/dist/features/passkeys/passkeys.service.js +350 -0
  203. package/dist/features/passkeys/passkeys.service.js.map +1 -0
  204. package/dist/features/passwordless/passwordless-auth.service.d.ts +152 -0
  205. package/dist/features/passwordless/passwordless-auth.service.js +304 -0
  206. package/dist/features/passwordless/passwordless-auth.service.js.map +1 -0
  207. package/dist/features/passwordless/passwordless.controller.d.ts +75 -0
  208. package/dist/features/passwordless/passwordless.controller.js +163 -0
  209. package/dist/features/passwordless/passwordless.controller.js.map +1 -0
  210. package/dist/features/passwordless/passwordless.dto.d.ts +29 -0
  211. package/dist/features/passwordless/passwordless.dto.js +101 -0
  212. package/dist/features/passwordless/passwordless.dto.js.map +1 -0
  213. package/dist/features/passwords/password-auth.service.d.ts +154 -0
  214. package/dist/features/passwords/password-auth.service.js +317 -0
  215. package/dist/features/passwords/password-auth.service.js.map +1 -0
  216. package/dist/features/passwords/password-policy.service.d.ts +63 -0
  217. package/dist/features/passwords/password-policy.service.js +175 -0
  218. package/dist/features/passwords/password-policy.service.js.map +1 -0
  219. package/dist/features/passwords/password.controller.d.ts +95 -0
  220. package/dist/features/passwords/password.controller.js +193 -0
  221. package/dist/features/passwords/password.controller.js.map +1 -0
  222. package/dist/features/passwords/password.dto.d.ts +36 -0
  223. package/dist/features/passwords/password.dto.js +140 -0
  224. package/dist/features/passwords/password.dto.js.map +1 -0
  225. package/dist/features/sessions/session.service.d.ts +132 -0
  226. package/dist/features/sessions/session.service.js +308 -0
  227. package/dist/features/sessions/session.service.js.map +1 -0
  228. package/dist/features/sessions/session.types.d.ts +34 -0
  229. package/dist/features/sessions/session.types.js +3 -0
  230. package/dist/features/sessions/session.types.js.map +1 -0
  231. package/dist/features/settings/settings.defaults.d.ts +2 -0
  232. package/dist/features/settings/settings.defaults.js +7 -0
  233. package/dist/features/settings/settings.defaults.js.map +1 -0
  234. package/dist/features/settings/settings.service.d.ts +44 -0
  235. package/dist/features/settings/settings.service.js +112 -0
  236. package/dist/features/settings/settings.service.js.map +1 -0
  237. package/dist/features/settings/settings.types.d.ts +133 -0
  238. package/dist/features/settings/settings.types.js +3 -0
  239. package/dist/features/settings/settings.types.js.map +1 -0
  240. package/dist/features/settings/settings.validation.d.ts +33 -0
  241. package/dist/features/settings/settings.validation.js +614 -0
  242. package/dist/features/settings/settings.validation.js.map +1 -0
  243. package/dist/features/sign-in/sign-in-challenges.service.d.ts +54 -0
  244. package/dist/features/sign-in/sign-in-challenges.service.js +104 -0
  245. package/dist/features/sign-in/sign-in-challenges.service.js.map +1 -0
  246. package/dist/features/sign-in/sign-in.service.d.ts +127 -0
  247. package/dist/features/sign-in/sign-in.service.js +248 -0
  248. package/dist/features/sign-in/sign-in.service.js.map +1 -0
  249. package/dist/features/sign-in/sign-in.types.d.ts +22 -0
  250. package/dist/features/sign-in/sign-in.types.js +3 -0
  251. package/dist/features/sign-in/sign-in.types.js.map +1 -0
  252. package/dist/features/signing-keys/jwks.controller.d.ts +17 -0
  253. package/dist/features/signing-keys/jwks.controller.js +51 -0
  254. package/dist/features/signing-keys/jwks.controller.js.map +1 -0
  255. package/dist/features/signing-keys/signing-keys.service.d.ts +67 -0
  256. package/dist/features/signing-keys/signing-keys.service.js +142 -0
  257. package/dist/features/signing-keys/signing-keys.service.js.map +1 -0
  258. package/dist/features/social/social-auth.service.d.ts +100 -0
  259. package/dist/features/social/social-auth.service.js +232 -0
  260. package/dist/features/social/social-auth.service.js.map +1 -0
  261. package/dist/features/social/social-providers.service.d.ts +97 -0
  262. package/dist/features/social/social-providers.service.js +214 -0
  263. package/dist/features/social/social-providers.service.js.map +1 -0
  264. package/dist/features/social/social.controller.d.ts +54 -0
  265. package/dist/features/social/social.controller.js +124 -0
  266. package/dist/features/social/social.controller.js.map +1 -0
  267. package/dist/features/social/social.dto.d.ts +11 -0
  268. package/dist/features/social/social.dto.js +38 -0
  269. package/dist/features/social/social.dto.js.map +1 -0
  270. package/dist/features/two-factor/two-factor.controller.d.ts +84 -0
  271. package/dist/features/two-factor/two-factor.controller.js +174 -0
  272. package/dist/features/two-factor/two-factor.controller.js.map +1 -0
  273. package/dist/features/two-factor/two-factor.dto.d.ts +10 -0
  274. package/dist/features/two-factor/two-factor.dto.js +37 -0
  275. package/dist/features/two-factor/two-factor.dto.js.map +1 -0
  276. package/dist/features/two-factor/two-factor.service.d.ts +171 -0
  277. package/dist/features/two-factor/two-factor.service.js +348 -0
  278. package/dist/features/two-factor/two-factor.service.js.map +1 -0
  279. package/dist/features/users/sign-in-methods.service.d.ts +40 -0
  280. package/dist/features/users/sign-in-methods.service.js +81 -0
  281. package/dist/features/users/sign-in-methods.service.js.map +1 -0
  282. package/dist/features/users/sign-up-rules.d.ts +12 -0
  283. package/dist/features/users/sign-up-rules.js +29 -0
  284. package/dist/features/users/sign-up-rules.js.map +1 -0
  285. package/dist/features/users/users.service.d.ts +246 -0
  286. package/dist/features/users/users.service.js +509 -0
  287. package/dist/features/users/users.service.js.map +1 -0
  288. package/dist/features/users/users.types.d.ts +24 -0
  289. package/dist/features/users/users.types.js +3 -0
  290. package/dist/features/users/users.types.js.map +1 -0
  291. package/dist/features/webhooks/webhook-delivery.worker.d.ts +55 -0
  292. package/dist/features/webhooks/webhook-delivery.worker.js +175 -0
  293. package/dist/features/webhooks/webhook-delivery.worker.js.map +1 -0
  294. package/dist/features/webhooks/webhook-signature.d.ts +28 -0
  295. package/dist/features/webhooks/webhook-signature.js +85 -0
  296. package/dist/features/webhooks/webhook-signature.js.map +1 -0
  297. package/dist/features/webhooks/webhooks.service.d.ts +144 -0
  298. package/dist/features/webhooks/webhooks.service.js +238 -0
  299. package/dist/features/webhooks/webhooks.service.js.map +1 -0
  300. package/dist/guards/auth.decorators.d.ts +65 -0
  301. package/dist/guards/auth.decorators.js +68 -0
  302. package/dist/guards/auth.decorators.js.map +1 -0
  303. package/dist/guards/auth.guard.d.ts +47 -0
  304. package/dist/guards/auth.guard.js +132 -0
  305. package/dist/guards/auth.guard.js.map +1 -0
  306. package/dist/index.d.ts +38 -0
  307. package/dist/index.js +95 -0
  308. package/dist/index.js.map +1 -0
  309. package/dist/integrations/console-email-sender.d.ts +15 -0
  310. package/dist/integrations/console-email-sender.js +26 -0
  311. package/dist/integrations/console-email-sender.js.map +1 -0
  312. package/dist/integrations/msg91-sms-sender.d.ts +28 -0
  313. package/dist/integrations/msg91-sms-sender.js +46 -0
  314. package/dist/integrations/msg91-sms-sender.js.map +1 -0
  315. package/docs/README.md +39 -0
  316. package/docs/admin-api-keys-webhooks.md +147 -0
  317. package/docs/api-reference.md +175 -0
  318. package/docs/architecture.md +119 -0
  319. package/docs/client-integration.md +192 -0
  320. package/docs/code-walkthrough.md +273 -0
  321. package/docs/configuration.md +229 -0
  322. package/docs/endpoints/README.md +151 -0
  323. package/docs/endpoints/account.md +363 -0
  324. package/docs/endpoints/admin.md +422 -0
  325. package/docs/endpoints/email-password.md +261 -0
  326. package/docs/endpoints/organizations.md +192 -0
  327. package/docs/endpoints/passkeys.md +195 -0
  328. package/docs/endpoints/passwordless.md +214 -0
  329. package/docs/endpoints/social.md +116 -0
  330. package/docs/endpoints/two-factor.md +146 -0
  331. package/docs/error-codes.md +100 -0
  332. package/docs/events.md +83 -0
  333. package/docs/getting-started.md +139 -0
  334. package/docs/manual-testing.md +215 -0
  335. package/docs/organizations.md +86 -0
  336. package/docs/production-checklist.md +60 -0
  337. package/docs/protecting-routes.md +147 -0
  338. package/docs/security.md +61 -0
  339. package/docs/sign-in-flows.md +294 -0
  340. package/package.json +92 -4
@@ -0,0 +1,3178 @@
1
+ {
2
+ "info": {
3
+ "name": "@techelusive/nest-auth (local playground)",
4
+ "description": "Every endpoint of @techelusive/nest-auth.\n\n1. Start the playground (npm run playground) and open http://localhost:3000/dev to watch emails, SMS and events.\n2. Run requests top to bottom inside a folder. Tokens, codes and links are captured automatically into collection variables.\n3. Change {{email}} / {{password}} in the collection variables to test other users.",
5
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
6
+ },
7
+ "auth": {
8
+ "type": "bearer",
9
+ "bearer": [
10
+ {
11
+ "key": "token",
12
+ "value": "{{accessToken}}",
13
+ "type": "string"
14
+ }
15
+ ]
16
+ },
17
+ "event": [
18
+ {
19
+ "listen": "test",
20
+ "script": {
21
+ "type": "text/javascript",
22
+ "exec": [
23
+ "let body = {};",
24
+ "try { body = pm.response.json(); } catch (error) { return; }",
25
+ "pm.test(\"response has a success field\", () => pm.expect(body).to.have.property(\"success\"));",
26
+ "if (body.success === false) console.log(\"Error code:\", body.code, \"-\", body.message);",
27
+ "// A deactivated account offers reactivation: keep the token for \"Reactivate\".",
28
+ "if (body.reactivationToken) pm.collectionVariables.set(\"reactivationToken\", body.reactivationToken);"
29
+ ]
30
+ }
31
+ }
32
+ ],
33
+ "variable": [
34
+ {
35
+ "key": "baseUrl",
36
+ "value": "http://localhost:3000"
37
+ },
38
+ {
39
+ "key": "email",
40
+ "value": "asha@example.com"
41
+ },
42
+ {
43
+ "key": "password",
44
+ "value": "correct horse battery"
45
+ },
46
+ {
47
+ "key": "newPassword",
48
+ "value": "a brand new passphrase"
49
+ },
50
+ {
51
+ "key": "secondEmail",
52
+ "value": "ravi@example.com"
53
+ },
54
+ {
55
+ "key": "phoneNumber",
56
+ "value": "+919876543210"
57
+ },
58
+ {
59
+ "key": "provider",
60
+ "value": "google"
61
+ },
62
+ {
63
+ "key": "socialToken",
64
+ "value": "paste-the-provider-token-here"
65
+ },
66
+ {
67
+ "key": "accessToken",
68
+ "value": ""
69
+ },
70
+ {
71
+ "key": "refreshToken",
72
+ "value": ""
73
+ },
74
+ {
75
+ "key": "sessionId",
76
+ "value": ""
77
+ },
78
+ {
79
+ "key": "userId",
80
+ "value": ""
81
+ },
82
+ {
83
+ "key": "challengeToken",
84
+ "value": ""
85
+ },
86
+ {
87
+ "key": "reactivationToken",
88
+ "value": ""
89
+ },
90
+ {
91
+ "key": "verificationToken",
92
+ "value": ""
93
+ },
94
+ {
95
+ "key": "resetToken",
96
+ "value": ""
97
+ },
98
+ {
99
+ "key": "magicLinkToken",
100
+ "value": ""
101
+ },
102
+ {
103
+ "key": "emailCode",
104
+ "value": ""
105
+ },
106
+ {
107
+ "key": "smsCode",
108
+ "value": ""
109
+ },
110
+ {
111
+ "key": "totpSecret",
112
+ "value": ""
113
+ },
114
+ {
115
+ "key": "totpCode",
116
+ "value": ""
117
+ },
118
+ {
119
+ "key": "backupCode",
120
+ "value": ""
121
+ },
122
+ {
123
+ "key": "invitationToken",
124
+ "value": ""
125
+ },
126
+ {
127
+ "key": "organizationId",
128
+ "value": ""
129
+ },
130
+ {
131
+ "key": "memberUserId",
132
+ "value": ""
133
+ },
134
+ {
135
+ "key": "invitationId",
136
+ "value": ""
137
+ },
138
+ {
139
+ "key": "passkeyId",
140
+ "value": ""
141
+ },
142
+ {
143
+ "key": "apiKey",
144
+ "value": ""
145
+ },
146
+ {
147
+ "key": "apiKeyId",
148
+ "value": ""
149
+ },
150
+ {
151
+ "key": "webhookId",
152
+ "value": ""
153
+ },
154
+ {
155
+ "key": "webhookSecret",
156
+ "value": ""
157
+ },
158
+ {
159
+ "key": "deliveryId",
160
+ "value": ""
161
+ },
162
+ {
163
+ "key": "organizationSlug",
164
+ "value": "acme-travels"
165
+ },
166
+ {
167
+ "key": "changedEmail",
168
+ "value": "asha.new@example.com"
169
+ },
170
+ {
171
+ "key": "emailChangeToken",
172
+ "value": ""
173
+ }
174
+ ],
175
+ "item": [
176
+ {
177
+ "name": "1. Email + password",
178
+ "item": [
179
+ {
180
+ "name": "Register",
181
+ "event": [
182
+ {
183
+ "listen": "test",
184
+ "script": {
185
+ "type": "text/javascript",
186
+ "exec": [
187
+ "const body = pm.response.json();",
188
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
189
+ "if (read(body, \"accessToken\") !== undefined) { pm.collectionVariables.set(\"accessToken\", read(body, \"accessToken\")); console.log(\"saved accessToken\"); }",
190
+ "if (read(body, \"refreshToken\") !== undefined) { pm.collectionVariables.set(\"refreshToken\", read(body, \"refreshToken\")); console.log(\"saved refreshToken\"); }",
191
+ "if (read(body, \"sessionId\") !== undefined) { pm.collectionVariables.set(\"sessionId\", read(body, \"sessionId\")); console.log(\"saved sessionId\"); }",
192
+ "if (read(body, \"user.id\") !== undefined) { pm.collectionVariables.set(\"userId\", read(body, \"user.id\")); console.log(\"saved userId\"); }",
193
+ "if (read(body, \"challengeToken\") !== undefined) { pm.collectionVariables.set(\"challengeToken\", read(body, \"challengeToken\")); console.log(\"saved challengeToken\"); }"
194
+ ]
195
+ }
196
+ }
197
+ ],
198
+ "request": {
199
+ "method": "POST",
200
+ "description": "Default settings: returns verification_required and emails a verification link (see the dev inbox).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
201
+ "auth": {
202
+ "type": "noauth"
203
+ },
204
+ "header": [
205
+ {
206
+ "key": "Content-Type",
207
+ "value": "application/json"
208
+ }
209
+ ],
210
+ "url": {
211
+ "raw": "{{baseUrl}}/auth/register",
212
+ "host": [
213
+ "{{baseUrl}}"
214
+ ],
215
+ "path": [
216
+ "auth",
217
+ "register"
218
+ ]
219
+ },
220
+ "body": {
221
+ "mode": "raw",
222
+ "raw": "{\n \"email\": \"{{email}}\",\n \"password\": \"{{password}}\",\n \"firstName\": \"Asha\",\n \"lastName\": \"Rao\",\n \"acceptTerms\": true,\n \"acceptPrivacyPolicy\": true\n}",
223
+ "options": {
224
+ "raw": {
225
+ "language": "json"
226
+ }
227
+ }
228
+ }
229
+ }
230
+ },
231
+ {
232
+ "name": "Resend verification email",
233
+ "event": [],
234
+ "request": {
235
+ "method": "POST",
236
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
237
+ "auth": {
238
+ "type": "noauth"
239
+ },
240
+ "header": [
241
+ {
242
+ "key": "Content-Type",
243
+ "value": "application/json"
244
+ }
245
+ ],
246
+ "url": {
247
+ "raw": "{{baseUrl}}/auth/email/send-verification",
248
+ "host": [
249
+ "{{baseUrl}}"
250
+ ],
251
+ "path": [
252
+ "auth",
253
+ "email",
254
+ "send-verification"
255
+ ]
256
+ },
257
+ "body": {
258
+ "mode": "raw",
259
+ "raw": "{\n \"email\": \"{{email}}\"\n}",
260
+ "options": {
261
+ "raw": {
262
+ "language": "json"
263
+ }
264
+ }
265
+ }
266
+ }
267
+ },
268
+ {
269
+ "name": "Verify email (token from inbox)",
270
+ "event": [
271
+ {
272
+ "listen": "prerequest",
273
+ "script": {
274
+ "type": "text/javascript",
275
+ "exec": [
276
+ "const to = pm.variables.replaceIn(\"{{email}}\");",
277
+ "pm.sendRequest(pm.variables.replaceIn(\"{{baseUrl}}\") + \"/dev/api/inbox/latest?to=\" + encodeURIComponent(to) + \"&type=verify_email\", (error, response) => {",
278
+ " if (error || response.code !== 200) { console.warn(\"No message in the dev inbox yet: send it first.\"); return; }",
279
+ " pm.collectionVariables.set(\"verificationToken\", response.json().token);",
280
+ " console.log(\"verificationToken taken from the dev inbox\");",
281
+ "});"
282
+ ]
283
+ }
284
+ }
285
+ ],
286
+ "request": {
287
+ "method": "POST",
288
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
289
+ "auth": {
290
+ "type": "noauth"
291
+ },
292
+ "header": [
293
+ {
294
+ "key": "Content-Type",
295
+ "value": "application/json"
296
+ }
297
+ ],
298
+ "url": {
299
+ "raw": "{{baseUrl}}/auth/email/verify",
300
+ "host": [
301
+ "{{baseUrl}}"
302
+ ],
303
+ "path": [
304
+ "auth",
305
+ "email",
306
+ "verify"
307
+ ]
308
+ },
309
+ "body": {
310
+ "mode": "raw",
311
+ "raw": "{\n \"token\": \"{{verificationToken}}\"\n}",
312
+ "options": {
313
+ "raw": {
314
+ "language": "json"
315
+ }
316
+ }
317
+ }
318
+ }
319
+ },
320
+ {
321
+ "name": "Login",
322
+ "event": [
323
+ {
324
+ "listen": "test",
325
+ "script": {
326
+ "type": "text/javascript",
327
+ "exec": [
328
+ "const body = pm.response.json();",
329
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
330
+ "if (read(body, \"accessToken\") !== undefined) { pm.collectionVariables.set(\"accessToken\", read(body, \"accessToken\")); console.log(\"saved accessToken\"); }",
331
+ "if (read(body, \"refreshToken\") !== undefined) { pm.collectionVariables.set(\"refreshToken\", read(body, \"refreshToken\")); console.log(\"saved refreshToken\"); }",
332
+ "if (read(body, \"sessionId\") !== undefined) { pm.collectionVariables.set(\"sessionId\", read(body, \"sessionId\")); console.log(\"saved sessionId\"); }",
333
+ "if (read(body, \"user.id\") !== undefined) { pm.collectionVariables.set(\"userId\", read(body, \"user.id\")); console.log(\"saved userId\"); }",
334
+ "if (read(body, \"challengeToken\") !== undefined) { pm.collectionVariables.set(\"challengeToken\", read(body, \"challengeToken\")); console.log(\"saved challengeToken\"); }"
335
+ ]
336
+ }
337
+ }
338
+ ],
339
+ "request": {
340
+ "method": "POST",
341
+ "description": "Saves accessToken / refreshToken automatically. If 2FA is on, saves challengeToken: then run \"Two-factor > Verify 2FA sign-in\".\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
342
+ "auth": {
343
+ "type": "noauth"
344
+ },
345
+ "header": [
346
+ {
347
+ "key": "Content-Type",
348
+ "value": "application/json"
349
+ }
350
+ ],
351
+ "url": {
352
+ "raw": "{{baseUrl}}/auth/login",
353
+ "host": [
354
+ "{{baseUrl}}"
355
+ ],
356
+ "path": [
357
+ "auth",
358
+ "login"
359
+ ]
360
+ },
361
+ "body": {
362
+ "mode": "raw",
363
+ "raw": "{\n \"email\": \"{{email}}\",\n \"password\": \"{{password}}\"\n}",
364
+ "options": {
365
+ "raw": {
366
+ "language": "json"
367
+ }
368
+ }
369
+ }
370
+ }
371
+ },
372
+ {
373
+ "name": "Forgot password",
374
+ "event": [],
375
+ "request": {
376
+ "method": "POST",
377
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
378
+ "auth": {
379
+ "type": "noauth"
380
+ },
381
+ "header": [
382
+ {
383
+ "key": "Content-Type",
384
+ "value": "application/json"
385
+ }
386
+ ],
387
+ "url": {
388
+ "raw": "{{baseUrl}}/auth/password/forgot",
389
+ "host": [
390
+ "{{baseUrl}}"
391
+ ],
392
+ "path": [
393
+ "auth",
394
+ "password",
395
+ "forgot"
396
+ ]
397
+ },
398
+ "body": {
399
+ "mode": "raw",
400
+ "raw": "{\n \"email\": \"{{email}}\"\n}",
401
+ "options": {
402
+ "raw": {
403
+ "language": "json"
404
+ }
405
+ }
406
+ }
407
+ }
408
+ },
409
+ {
410
+ "name": "Reset password (token from inbox)",
411
+ "event": [
412
+ {
413
+ "listen": "prerequest",
414
+ "script": {
415
+ "type": "text/javascript",
416
+ "exec": [
417
+ "const to = pm.variables.replaceIn(\"{{email}}\");",
418
+ "pm.sendRequest(pm.variables.replaceIn(\"{{baseUrl}}\") + \"/dev/api/inbox/latest?to=\" + encodeURIComponent(to) + \"&type=reset_password\", (error, response) => {",
419
+ " if (error || response.code !== 200) { console.warn(\"No message in the dev inbox yet: send it first.\"); return; }",
420
+ " pm.collectionVariables.set(\"resetToken\", response.json().token);",
421
+ " console.log(\"resetToken taken from the dev inbox\");",
422
+ "});"
423
+ ]
424
+ }
425
+ }
426
+ ],
427
+ "request": {
428
+ "method": "POST",
429
+ "description": "Signs out every device. Afterwards sign in with a brand new passphrase.\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
430
+ "auth": {
431
+ "type": "noauth"
432
+ },
433
+ "header": [
434
+ {
435
+ "key": "Content-Type",
436
+ "value": "application/json"
437
+ }
438
+ ],
439
+ "url": {
440
+ "raw": "{{baseUrl}}/auth/password/reset",
441
+ "host": [
442
+ "{{baseUrl}}"
443
+ ],
444
+ "path": [
445
+ "auth",
446
+ "password",
447
+ "reset"
448
+ ]
449
+ },
450
+ "body": {
451
+ "mode": "raw",
452
+ "raw": "{\n \"token\": \"{{resetToken}}\",\n \"newPassword\": \"{{newPassword}}\"\n}",
453
+ "options": {
454
+ "raw": {
455
+ "language": "json"
456
+ }
457
+ }
458
+ }
459
+ }
460
+ },
461
+ {
462
+ "name": "Change password",
463
+ "event": [],
464
+ "request": {
465
+ "method": "POST",
466
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
467
+ "header": [
468
+ {
469
+ "key": "Content-Type",
470
+ "value": "application/json"
471
+ }
472
+ ],
473
+ "url": {
474
+ "raw": "{{baseUrl}}/auth/password/change",
475
+ "host": [
476
+ "{{baseUrl}}"
477
+ ],
478
+ "path": [
479
+ "auth",
480
+ "password",
481
+ "change"
482
+ ]
483
+ },
484
+ "body": {
485
+ "mode": "raw",
486
+ "raw": "{\n \"currentPassword\": \"{{password}}\",\n \"newPassword\": \"{{newPassword}}\"\n}",
487
+ "options": {
488
+ "raw": {
489
+ "language": "json"
490
+ }
491
+ }
492
+ }
493
+ }
494
+ }
495
+ ]
496
+ },
497
+ {
498
+ "name": "2. Passwordless",
499
+ "item": [
500
+ {
501
+ "name": "Send email code",
502
+ "event": [],
503
+ "request": {
504
+ "method": "POST",
505
+ "description": "Needs emailOtp.enabled (the playground turns it on).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
506
+ "auth": {
507
+ "type": "noauth"
508
+ },
509
+ "header": [
510
+ {
511
+ "key": "Content-Type",
512
+ "value": "application/json"
513
+ }
514
+ ],
515
+ "url": {
516
+ "raw": "{{baseUrl}}/auth/email/send-otp",
517
+ "host": [
518
+ "{{baseUrl}}"
519
+ ],
520
+ "path": [
521
+ "auth",
522
+ "email",
523
+ "send-otp"
524
+ ]
525
+ },
526
+ "body": {
527
+ "mode": "raw",
528
+ "raw": "{\n \"email\": \"{{secondEmail}}\"\n}",
529
+ "options": {
530
+ "raw": {
531
+ "language": "json"
532
+ }
533
+ }
534
+ }
535
+ }
536
+ },
537
+ {
538
+ "name": "Verify email code (code from inbox)",
539
+ "event": [
540
+ {
541
+ "listen": "prerequest",
542
+ "script": {
543
+ "type": "text/javascript",
544
+ "exec": [
545
+ "const to = pm.variables.replaceIn(\"{{secondEmail}}\");",
546
+ "pm.sendRequest(pm.variables.replaceIn(\"{{baseUrl}}\") + \"/dev/api/inbox/latest?to=\" + encodeURIComponent(to) + \"&type=sign_in_code\", (error, response) => {",
547
+ " if (error || response.code !== 200) { console.warn(\"No message in the dev inbox yet: send it first.\"); return; }",
548
+ " pm.collectionVariables.set(\"emailCode\", response.json().code);",
549
+ " console.log(\"emailCode taken from the dev inbox\");",
550
+ "});"
551
+ ]
552
+ }
553
+ },
554
+ {
555
+ "listen": "test",
556
+ "script": {
557
+ "type": "text/javascript",
558
+ "exec": [
559
+ "const body = pm.response.json();",
560
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
561
+ "if (read(body, \"accessToken\") !== undefined) { pm.collectionVariables.set(\"accessToken\", read(body, \"accessToken\")); console.log(\"saved accessToken\"); }",
562
+ "if (read(body, \"refreshToken\") !== undefined) { pm.collectionVariables.set(\"refreshToken\", read(body, \"refreshToken\")); console.log(\"saved refreshToken\"); }",
563
+ "if (read(body, \"sessionId\") !== undefined) { pm.collectionVariables.set(\"sessionId\", read(body, \"sessionId\")); console.log(\"saved sessionId\"); }",
564
+ "if (read(body, \"user.id\") !== undefined) { pm.collectionVariables.set(\"userId\", read(body, \"user.id\")); console.log(\"saved userId\"); }",
565
+ "if (read(body, \"challengeToken\") !== undefined) { pm.collectionVariables.set(\"challengeToken\", read(body, \"challengeToken\")); console.log(\"saved challengeToken\"); }"
566
+ ]
567
+ }
568
+ }
569
+ ],
570
+ "request": {
571
+ "method": "POST",
572
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
573
+ "auth": {
574
+ "type": "noauth"
575
+ },
576
+ "header": [
577
+ {
578
+ "key": "Content-Type",
579
+ "value": "application/json"
580
+ }
581
+ ],
582
+ "url": {
583
+ "raw": "{{baseUrl}}/auth/email/verify-otp",
584
+ "host": [
585
+ "{{baseUrl}}"
586
+ ],
587
+ "path": [
588
+ "auth",
589
+ "email",
590
+ "verify-otp"
591
+ ]
592
+ },
593
+ "body": {
594
+ "mode": "raw",
595
+ "raw": "{\n \"email\": \"{{secondEmail}}\",\n \"code\": \"{{emailCode}}\",\n \"firstName\": \"Ravi\",\n \"lastName\": \"Kumar\",\n \"acceptTerms\": true,\n \"acceptPrivacyPolicy\": true\n}",
596
+ "options": {
597
+ "raw": {
598
+ "language": "json"
599
+ }
600
+ }
601
+ }
602
+ }
603
+ },
604
+ {
605
+ "name": "Send magic link",
606
+ "event": [],
607
+ "request": {
608
+ "method": "POST",
609
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
610
+ "auth": {
611
+ "type": "noauth"
612
+ },
613
+ "header": [
614
+ {
615
+ "key": "Content-Type",
616
+ "value": "application/json"
617
+ }
618
+ ],
619
+ "url": {
620
+ "raw": "{{baseUrl}}/auth/magic-link/send",
621
+ "host": [
622
+ "{{baseUrl}}"
623
+ ],
624
+ "path": [
625
+ "auth",
626
+ "magic-link",
627
+ "send"
628
+ ]
629
+ },
630
+ "body": {
631
+ "mode": "raw",
632
+ "raw": "{\n \"email\": \"{{secondEmail}}\"\n}",
633
+ "options": {
634
+ "raw": {
635
+ "language": "json"
636
+ }
637
+ }
638
+ }
639
+ }
640
+ },
641
+ {
642
+ "name": "Verify magic link (token from inbox)",
643
+ "event": [
644
+ {
645
+ "listen": "prerequest",
646
+ "script": {
647
+ "type": "text/javascript",
648
+ "exec": [
649
+ "const to = pm.variables.replaceIn(\"{{secondEmail}}\");",
650
+ "pm.sendRequest(pm.variables.replaceIn(\"{{baseUrl}}\") + \"/dev/api/inbox/latest?to=\" + encodeURIComponent(to) + \"&type=magic_sign_in\", (error, response) => {",
651
+ " if (error || response.code !== 200) { console.warn(\"No message in the dev inbox yet: send it first.\"); return; }",
652
+ " pm.collectionVariables.set(\"magicLinkToken\", response.json().token);",
653
+ " console.log(\"magicLinkToken taken from the dev inbox\");",
654
+ "});"
655
+ ]
656
+ }
657
+ },
658
+ {
659
+ "listen": "test",
660
+ "script": {
661
+ "type": "text/javascript",
662
+ "exec": [
663
+ "const body = pm.response.json();",
664
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
665
+ "if (read(body, \"accessToken\") !== undefined) { pm.collectionVariables.set(\"accessToken\", read(body, \"accessToken\")); console.log(\"saved accessToken\"); }",
666
+ "if (read(body, \"refreshToken\") !== undefined) { pm.collectionVariables.set(\"refreshToken\", read(body, \"refreshToken\")); console.log(\"saved refreshToken\"); }",
667
+ "if (read(body, \"sessionId\") !== undefined) { pm.collectionVariables.set(\"sessionId\", read(body, \"sessionId\")); console.log(\"saved sessionId\"); }",
668
+ "if (read(body, \"user.id\") !== undefined) { pm.collectionVariables.set(\"userId\", read(body, \"user.id\")); console.log(\"saved userId\"); }",
669
+ "if (read(body, \"challengeToken\") !== undefined) { pm.collectionVariables.set(\"challengeToken\", read(body, \"challengeToken\")); console.log(\"saved challengeToken\"); }"
670
+ ]
671
+ }
672
+ }
673
+ ],
674
+ "request": {
675
+ "method": "POST",
676
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
677
+ "auth": {
678
+ "type": "noauth"
679
+ },
680
+ "header": [
681
+ {
682
+ "key": "Content-Type",
683
+ "value": "application/json"
684
+ }
685
+ ],
686
+ "url": {
687
+ "raw": "{{baseUrl}}/auth/magic-link/verify",
688
+ "host": [
689
+ "{{baseUrl}}"
690
+ ],
691
+ "path": [
692
+ "auth",
693
+ "magic-link",
694
+ "verify"
695
+ ]
696
+ },
697
+ "body": {
698
+ "mode": "raw",
699
+ "raw": "{\n \"token\": \"{{magicLinkToken}}\",\n \"firstName\": \"Ravi\",\n \"lastName\": \"Kumar\",\n \"acceptTerms\": true,\n \"acceptPrivacyPolicy\": true\n}",
700
+ "options": {
701
+ "raw": {
702
+ "language": "json"
703
+ }
704
+ }
705
+ }
706
+ }
707
+ },
708
+ {
709
+ "name": "Send phone code",
710
+ "event": [],
711
+ "request": {
712
+ "method": "POST",
713
+ "description": "The playground delivers SMS to the dev inbox instead of a real phone.\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
714
+ "auth": {
715
+ "type": "noauth"
716
+ },
717
+ "header": [
718
+ {
719
+ "key": "Content-Type",
720
+ "value": "application/json"
721
+ }
722
+ ],
723
+ "url": {
724
+ "raw": "{{baseUrl}}/auth/phone/send-otp",
725
+ "host": [
726
+ "{{baseUrl}}"
727
+ ],
728
+ "path": [
729
+ "auth",
730
+ "phone",
731
+ "send-otp"
732
+ ]
733
+ },
734
+ "body": {
735
+ "mode": "raw",
736
+ "raw": "{\n \"phoneNumber\": \"{{phoneNumber}}\"\n}",
737
+ "options": {
738
+ "raw": {
739
+ "language": "json"
740
+ }
741
+ }
742
+ }
743
+ }
744
+ },
745
+ {
746
+ "name": "Verify phone code (code from inbox)",
747
+ "event": [
748
+ {
749
+ "listen": "prerequest",
750
+ "script": {
751
+ "type": "text/javascript",
752
+ "exec": [
753
+ "const to = pm.variables.replaceIn(\"{{phoneNumber}}\");",
754
+ "pm.sendRequest(pm.variables.replaceIn(\"{{baseUrl}}\") + \"/dev/api/inbox/latest?to=\" + encodeURIComponent(to) + \"&type=sms_code\", (error, response) => {",
755
+ " if (error || response.code !== 200) { console.warn(\"No message in the dev inbox yet: send it first.\"); return; }",
756
+ " pm.collectionVariables.set(\"smsCode\", response.json().code);",
757
+ " console.log(\"smsCode taken from the dev inbox\");",
758
+ "});"
759
+ ]
760
+ }
761
+ },
762
+ {
763
+ "listen": "test",
764
+ "script": {
765
+ "type": "text/javascript",
766
+ "exec": [
767
+ "const body = pm.response.json();",
768
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
769
+ "if (read(body, \"accessToken\") !== undefined) { pm.collectionVariables.set(\"accessToken\", read(body, \"accessToken\")); console.log(\"saved accessToken\"); }",
770
+ "if (read(body, \"refreshToken\") !== undefined) { pm.collectionVariables.set(\"refreshToken\", read(body, \"refreshToken\")); console.log(\"saved refreshToken\"); }",
771
+ "if (read(body, \"sessionId\") !== undefined) { pm.collectionVariables.set(\"sessionId\", read(body, \"sessionId\")); console.log(\"saved sessionId\"); }",
772
+ "if (read(body, \"user.id\") !== undefined) { pm.collectionVariables.set(\"userId\", read(body, \"user.id\")); console.log(\"saved userId\"); }",
773
+ "if (read(body, \"challengeToken\") !== undefined) { pm.collectionVariables.set(\"challengeToken\", read(body, \"challengeToken\")); console.log(\"saved challengeToken\"); }"
774
+ ]
775
+ }
776
+ }
777
+ ],
778
+ "request": {
779
+ "method": "POST",
780
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
781
+ "auth": {
782
+ "type": "noauth"
783
+ },
784
+ "header": [
785
+ {
786
+ "key": "Content-Type",
787
+ "value": "application/json"
788
+ }
789
+ ],
790
+ "url": {
791
+ "raw": "{{baseUrl}}/auth/phone/verify-otp",
792
+ "host": [
793
+ "{{baseUrl}}"
794
+ ],
795
+ "path": [
796
+ "auth",
797
+ "phone",
798
+ "verify-otp"
799
+ ]
800
+ },
801
+ "body": {
802
+ "mode": "raw",
803
+ "raw": "{\n \"phoneNumber\": \"{{phoneNumber}}\",\n \"code\": \"{{smsCode}}\",\n \"firstName\": \"Meera\",\n \"lastName\": \"Shah\",\n \"acceptTerms\": true,\n \"acceptPrivacyPolicy\": true\n}",
804
+ "options": {
805
+ "raw": {
806
+ "language": "json"
807
+ }
808
+ }
809
+ }
810
+ }
811
+ }
812
+ ]
813
+ },
814
+ {
815
+ "name": "3. Account and sessions",
816
+ "item": [
817
+ {
818
+ "name": "Get my profile",
819
+ "event": [],
820
+ "request": {
821
+ "method": "GET",
822
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
823
+ "header": [],
824
+ "url": {
825
+ "raw": "{{baseUrl}}/auth/me",
826
+ "host": [
827
+ "{{baseUrl}}"
828
+ ],
829
+ "path": [
830
+ "auth",
831
+ "me"
832
+ ]
833
+ }
834
+ }
835
+ },
836
+ {
837
+ "name": "Update my profile",
838
+ "event": [],
839
+ "request": {
840
+ "method": "PATCH",
841
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
842
+ "header": [
843
+ {
844
+ "key": "Content-Type",
845
+ "value": "application/json"
846
+ }
847
+ ],
848
+ "url": {
849
+ "raw": "{{baseUrl}}/auth/me",
850
+ "host": [
851
+ "{{baseUrl}}"
852
+ ],
853
+ "path": [
854
+ "auth",
855
+ "me"
856
+ ]
857
+ },
858
+ "body": {
859
+ "mode": "raw",
860
+ "raw": "{\n \"firstName\": \"Asha\",\n \"lastName\": \"Rao-Mehta\",\n \"metadata\": {\n \"preferredLanguage\": \"hi\"\n }\n}",
861
+ "options": {
862
+ "raw": {
863
+ "language": "json"
864
+ }
865
+ }
866
+ }
867
+ }
868
+ },
869
+ {
870
+ "name": "My sign-in methods",
871
+ "event": [],
872
+ "request": {
873
+ "method": "GET",
874
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
875
+ "header": [],
876
+ "url": {
877
+ "raw": "{{baseUrl}}/auth/sign-in-methods",
878
+ "host": [
879
+ "{{baseUrl}}"
880
+ ],
881
+ "path": [
882
+ "auth",
883
+ "sign-in-methods"
884
+ ]
885
+ }
886
+ }
887
+ },
888
+ {
889
+ "name": "My devices",
890
+ "event": [],
891
+ "request": {
892
+ "method": "GET",
893
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
894
+ "header": [],
895
+ "url": {
896
+ "raw": "{{baseUrl}}/auth/sessions",
897
+ "host": [
898
+ "{{baseUrl}}"
899
+ ],
900
+ "path": [
901
+ "auth",
902
+ "sessions"
903
+ ]
904
+ }
905
+ }
906
+ },
907
+ {
908
+ "name": "Sign out one device",
909
+ "event": [],
910
+ "request": {
911
+ "method": "DELETE",
912
+ "description": "Uses <sessionId> (the current device unless you change it).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
913
+ "header": [],
914
+ "url": {
915
+ "raw": "{{baseUrl}}/auth/sessions/{{sessionId}}",
916
+ "host": [
917
+ "{{baseUrl}}"
918
+ ],
919
+ "path": [
920
+ "auth",
921
+ "sessions",
922
+ "{{sessionId}}"
923
+ ]
924
+ }
925
+ }
926
+ },
927
+ {
928
+ "name": "Refresh tokens",
929
+ "event": [
930
+ {
931
+ "listen": "test",
932
+ "script": {
933
+ "type": "text/javascript",
934
+ "exec": [
935
+ "const body = pm.response.json();",
936
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
937
+ "if (read(body, \"accessToken\") !== undefined) { pm.collectionVariables.set(\"accessToken\", read(body, \"accessToken\")); console.log(\"saved accessToken\"); }",
938
+ "if (read(body, \"refreshToken\") !== undefined) { pm.collectionVariables.set(\"refreshToken\", read(body, \"refreshToken\")); console.log(\"saved refreshToken\"); }"
939
+ ]
940
+ }
941
+ }
942
+ ],
943
+ "request": {
944
+ "method": "POST",
945
+ "description": "Send it twice with the same old token to see reuse detection end the session.\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
946
+ "auth": {
947
+ "type": "noauth"
948
+ },
949
+ "header": [
950
+ {
951
+ "key": "Content-Type",
952
+ "value": "application/json"
953
+ }
954
+ ],
955
+ "url": {
956
+ "raw": "{{baseUrl}}/auth/refresh",
957
+ "host": [
958
+ "{{baseUrl}}"
959
+ ],
960
+ "path": [
961
+ "auth",
962
+ "refresh"
963
+ ]
964
+ },
965
+ "body": {
966
+ "mode": "raw",
967
+ "raw": "{\n \"refreshToken\": \"{{refreshToken}}\"\n}",
968
+ "options": {
969
+ "raw": {
970
+ "language": "json"
971
+ }
972
+ }
973
+ }
974
+ }
975
+ },
976
+ {
977
+ "name": "Logout (this device)",
978
+ "event": [],
979
+ "request": {
980
+ "method": "POST",
981
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
982
+ "header": [],
983
+ "url": {
984
+ "raw": "{{baseUrl}}/auth/logout",
985
+ "host": [
986
+ "{{baseUrl}}"
987
+ ],
988
+ "path": [
989
+ "auth",
990
+ "logout"
991
+ ]
992
+ }
993
+ }
994
+ },
995
+ {
996
+ "name": "Logout everywhere",
997
+ "event": [],
998
+ "request": {
999
+ "method": "POST",
1000
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1001
+ "header": [],
1002
+ "url": {
1003
+ "raw": "{{baseUrl}}/auth/logout-all",
1004
+ "host": [
1005
+ "{{baseUrl}}"
1006
+ ],
1007
+ "path": [
1008
+ "auth",
1009
+ "logout-all"
1010
+ ]
1011
+ }
1012
+ }
1013
+ },
1014
+ {
1015
+ "name": "Deactivate my account",
1016
+ "event": [],
1017
+ "request": {
1018
+ "method": "POST",
1019
+ "description": "Then \"Login\" returns ACCOUNT_DEACTIVATED with a reactivationToken (saved automatically).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1020
+ "header": [],
1021
+ "url": {
1022
+ "raw": "{{baseUrl}}/auth/deactivate",
1023
+ "host": [
1024
+ "{{baseUrl}}"
1025
+ ],
1026
+ "path": [
1027
+ "auth",
1028
+ "deactivate"
1029
+ ]
1030
+ }
1031
+ }
1032
+ },
1033
+ {
1034
+ "name": "Reactivate",
1035
+ "event": [
1036
+ {
1037
+ "listen": "test",
1038
+ "script": {
1039
+ "type": "text/javascript",
1040
+ "exec": [
1041
+ "const body = pm.response.json();",
1042
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
1043
+ "if (read(body, \"accessToken\") !== undefined) { pm.collectionVariables.set(\"accessToken\", read(body, \"accessToken\")); console.log(\"saved accessToken\"); }",
1044
+ "if (read(body, \"refreshToken\") !== undefined) { pm.collectionVariables.set(\"refreshToken\", read(body, \"refreshToken\")); console.log(\"saved refreshToken\"); }",
1045
+ "if (read(body, \"sessionId\") !== undefined) { pm.collectionVariables.set(\"sessionId\", read(body, \"sessionId\")); console.log(\"saved sessionId\"); }",
1046
+ "if (read(body, \"user.id\") !== undefined) { pm.collectionVariables.set(\"userId\", read(body, \"user.id\")); console.log(\"saved userId\"); }",
1047
+ "if (read(body, \"challengeToken\") !== undefined) { pm.collectionVariables.set(\"challengeToken\", read(body, \"challengeToken\")); console.log(\"saved challengeToken\"); }"
1048
+ ]
1049
+ }
1050
+ }
1051
+ ],
1052
+ "request": {
1053
+ "method": "POST",
1054
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1055
+ "auth": {
1056
+ "type": "noauth"
1057
+ },
1058
+ "header": [
1059
+ {
1060
+ "key": "Content-Type",
1061
+ "value": "application/json"
1062
+ }
1063
+ ],
1064
+ "url": {
1065
+ "raw": "{{baseUrl}}/auth/reactivate",
1066
+ "host": [
1067
+ "{{baseUrl}}"
1068
+ ],
1069
+ "path": [
1070
+ "auth",
1071
+ "reactivate"
1072
+ ]
1073
+ },
1074
+ "body": {
1075
+ "mode": "raw",
1076
+ "raw": "{\n \"reactivationToken\": \"{{reactivationToken}}\"\n}",
1077
+ "options": {
1078
+ "raw": {
1079
+ "language": "json"
1080
+ }
1081
+ }
1082
+ }
1083
+ }
1084
+ },
1085
+ {
1086
+ "name": "Change my email",
1087
+ "event": [],
1088
+ "request": {
1089
+ "method": "POST",
1090
+ "description": "Sends a confirmation link to the new address. Accounts without a password leave out currentPassword but must have signed in within the last 10 minutes.\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1091
+ "header": [
1092
+ {
1093
+ "key": "Content-Type",
1094
+ "value": "application/json"
1095
+ }
1096
+ ],
1097
+ "url": {
1098
+ "raw": "{{baseUrl}}/auth/email/change",
1099
+ "host": [
1100
+ "{{baseUrl}}"
1101
+ ],
1102
+ "path": [
1103
+ "auth",
1104
+ "email",
1105
+ "change"
1106
+ ]
1107
+ },
1108
+ "body": {
1109
+ "mode": "raw",
1110
+ "raw": "{\n \"newEmail\": \"{{changedEmail}}\",\n \"currentPassword\": \"{{password}}\"\n}",
1111
+ "options": {
1112
+ "raw": {
1113
+ "language": "json"
1114
+ }
1115
+ }
1116
+ }
1117
+ }
1118
+ },
1119
+ {
1120
+ "name": "Confirm email change (token from inbox)",
1121
+ "event": [
1122
+ {
1123
+ "listen": "prerequest",
1124
+ "script": {
1125
+ "type": "text/javascript",
1126
+ "exec": [
1127
+ "const to = pm.variables.replaceIn(\"{{changedEmail}}\");",
1128
+ "pm.sendRequest(pm.variables.replaceIn(\"{{baseUrl}}\") + \"/dev/api/inbox/latest?to=\" + encodeURIComponent(to) + \"&type=confirm_email_change\", (error, response) => {",
1129
+ " if (error || response.code !== 200) { console.warn(\"No message in the dev inbox yet: send it first.\"); return; }",
1130
+ " pm.collectionVariables.set(\"emailChangeToken\", response.json().token);",
1131
+ " console.log(\"emailChangeToken taken from the dev inbox\");",
1132
+ "});"
1133
+ ]
1134
+ }
1135
+ }
1136
+ ],
1137
+ "request": {
1138
+ "method": "POST",
1139
+ "description": "Switches the email and tells the old address. Afterwards set the email variable to asha.new@example.com to keep signing in.\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1140
+ "auth": {
1141
+ "type": "noauth"
1142
+ },
1143
+ "header": [
1144
+ {
1145
+ "key": "Content-Type",
1146
+ "value": "application/json"
1147
+ }
1148
+ ],
1149
+ "url": {
1150
+ "raw": "{{baseUrl}}/auth/email/change/confirm",
1151
+ "host": [
1152
+ "{{baseUrl}}"
1153
+ ],
1154
+ "path": [
1155
+ "auth",
1156
+ "email",
1157
+ "change",
1158
+ "confirm"
1159
+ ]
1160
+ },
1161
+ "body": {
1162
+ "mode": "raw",
1163
+ "raw": "{\n \"token\": \"{{emailChangeToken}}\"\n}",
1164
+ "options": {
1165
+ "raw": {
1166
+ "language": "json"
1167
+ }
1168
+ }
1169
+ }
1170
+ }
1171
+ },
1172
+ {
1173
+ "name": "Download my data",
1174
+ "event": [],
1175
+ "request": {
1176
+ "method": "GET",
1177
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1178
+ "header": [],
1179
+ "url": {
1180
+ "raw": "{{baseUrl}}/auth/me/export",
1181
+ "host": [
1182
+ "{{baseUrl}}"
1183
+ ],
1184
+ "path": [
1185
+ "auth",
1186
+ "me",
1187
+ "export"
1188
+ ]
1189
+ }
1190
+ }
1191
+ },
1192
+ {
1193
+ "name": "Health check",
1194
+ "event": [],
1195
+ "request": {
1196
+ "method": "GET",
1197
+ "description": "200 when the database (and Redis, if used) answer, 503 otherwise.\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1198
+ "auth": {
1199
+ "type": "noauth"
1200
+ },
1201
+ "header": [],
1202
+ "url": {
1203
+ "raw": "{{baseUrl}}/auth/health",
1204
+ "host": [
1205
+ "{{baseUrl}}"
1206
+ ],
1207
+ "path": [
1208
+ "auth",
1209
+ "health"
1210
+ ]
1211
+ }
1212
+ }
1213
+ },
1214
+ {
1215
+ "name": "Delete my account",
1216
+ "event": [],
1217
+ "request": {
1218
+ "method": "DELETE",
1219
+ "description": "Permanent.\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1220
+ "header": [],
1221
+ "url": {
1222
+ "raw": "{{baseUrl}}/auth/me",
1223
+ "host": [
1224
+ "{{baseUrl}}"
1225
+ ],
1226
+ "path": [
1227
+ "auth",
1228
+ "me"
1229
+ ]
1230
+ }
1231
+ }
1232
+ }
1233
+ ]
1234
+ },
1235
+ {
1236
+ "name": "4. Two-factor",
1237
+ "item": [
1238
+ {
1239
+ "name": "2FA status",
1240
+ "event": [],
1241
+ "request": {
1242
+ "method": "GET",
1243
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1244
+ "header": [],
1245
+ "url": {
1246
+ "raw": "{{baseUrl}}/auth/2fa",
1247
+ "host": [
1248
+ "{{baseUrl}}"
1249
+ ],
1250
+ "path": [
1251
+ "auth",
1252
+ "2fa"
1253
+ ]
1254
+ }
1255
+ }
1256
+ },
1257
+ {
1258
+ "name": "Start 2FA setup",
1259
+ "event": [
1260
+ {
1261
+ "listen": "test",
1262
+ "script": {
1263
+ "type": "text/javascript",
1264
+ "exec": [
1265
+ "const body = pm.response.json();",
1266
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
1267
+ "if (read(body, \"secret\") !== undefined) { pm.collectionVariables.set(\"totpSecret\", read(body, \"secret\")); console.log(\"saved totpSecret\"); }"
1268
+ ]
1269
+ }
1270
+ }
1271
+ ],
1272
+ "request": {
1273
+ "method": "POST",
1274
+ "description": "Saves the secret. Scan authenticatorAppUrl with Google/Microsoft Authenticator if you want a real app too.\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1275
+ "header": [],
1276
+ "url": {
1277
+ "raw": "{{baseUrl}}/auth/2fa/setup",
1278
+ "host": [
1279
+ "{{baseUrl}}"
1280
+ ],
1281
+ "path": [
1282
+ "auth",
1283
+ "2fa",
1284
+ "setup"
1285
+ ]
1286
+ }
1287
+ }
1288
+ },
1289
+ {
1290
+ "name": "Enable 2FA (code computed for you)",
1291
+ "event": [
1292
+ {
1293
+ "listen": "prerequest",
1294
+ "script": {
1295
+ "type": "text/javascript",
1296
+ "exec": [
1297
+ "pm.sendRequest(pm.variables.replaceIn(\"{{baseUrl}}/dev/api/totp?secret={{totpSecret}}\"), (error, response) => {",
1298
+ " if (error || response.code !== 200) { console.warn(\"Run \\\"Start 2FA setup\\\" first.\"); return; }",
1299
+ " pm.collectionVariables.set(\"totpCode\", response.json().code);",
1300
+ "});"
1301
+ ]
1302
+ }
1303
+ },
1304
+ {
1305
+ "listen": "test",
1306
+ "script": {
1307
+ "type": "text/javascript",
1308
+ "exec": [
1309
+ "const body = pm.response.json();",
1310
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
1311
+ "if (read(body, \"backupCodes.0\") !== undefined) { pm.collectionVariables.set(\"backupCode\", read(body, \"backupCodes.0\")); console.log(\"saved backupCode\"); }"
1312
+ ]
1313
+ }
1314
+ }
1315
+ ],
1316
+ "request": {
1317
+ "method": "POST",
1318
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1319
+ "header": [
1320
+ {
1321
+ "key": "Content-Type",
1322
+ "value": "application/json"
1323
+ }
1324
+ ],
1325
+ "url": {
1326
+ "raw": "{{baseUrl}}/auth/2fa/enable",
1327
+ "host": [
1328
+ "{{baseUrl}}"
1329
+ ],
1330
+ "path": [
1331
+ "auth",
1332
+ "2fa",
1333
+ "enable"
1334
+ ]
1335
+ },
1336
+ "body": {
1337
+ "mode": "raw",
1338
+ "raw": "{\n \"code\": \"{{totpCode}}\"\n}",
1339
+ "options": {
1340
+ "raw": {
1341
+ "language": "json"
1342
+ }
1343
+ }
1344
+ }
1345
+ }
1346
+ },
1347
+ {
1348
+ "name": "Verify 2FA sign-in",
1349
+ "event": [
1350
+ {
1351
+ "listen": "prerequest",
1352
+ "script": {
1353
+ "type": "text/javascript",
1354
+ "exec": [
1355
+ "pm.sendRequest(pm.variables.replaceIn(\"{{baseUrl}}/dev/api/totp?secret={{totpSecret}}\"), (error, response) => {",
1356
+ " if (error || response.code !== 200) { console.warn(\"Run \\\"Start 2FA setup\\\" first.\"); return; }",
1357
+ " pm.collectionVariables.set(\"totpCode\", response.json().code);",
1358
+ "});"
1359
+ ]
1360
+ }
1361
+ },
1362
+ {
1363
+ "listen": "test",
1364
+ "script": {
1365
+ "type": "text/javascript",
1366
+ "exec": [
1367
+ "const body = pm.response.json();",
1368
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
1369
+ "if (read(body, \"accessToken\") !== undefined) { pm.collectionVariables.set(\"accessToken\", read(body, \"accessToken\")); console.log(\"saved accessToken\"); }",
1370
+ "if (read(body, \"refreshToken\") !== undefined) { pm.collectionVariables.set(\"refreshToken\", read(body, \"refreshToken\")); console.log(\"saved refreshToken\"); }",
1371
+ "if (read(body, \"sessionId\") !== undefined) { pm.collectionVariables.set(\"sessionId\", read(body, \"sessionId\")); console.log(\"saved sessionId\"); }",
1372
+ "if (read(body, \"user.id\") !== undefined) { pm.collectionVariables.set(\"userId\", read(body, \"user.id\")); console.log(\"saved userId\"); }",
1373
+ "if (read(body, \"challengeToken\") !== undefined) { pm.collectionVariables.set(\"challengeToken\", read(body, \"challengeToken\")); console.log(\"saved challengeToken\"); }"
1374
+ ]
1375
+ }
1376
+ }
1377
+ ],
1378
+ "request": {
1379
+ "method": "POST",
1380
+ "description": "A code works only once: wait for the next 30-second window before reusing, or put <backupCode> in \"code\".\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1381
+ "auth": {
1382
+ "type": "noauth"
1383
+ },
1384
+ "header": [
1385
+ {
1386
+ "key": "Content-Type",
1387
+ "value": "application/json"
1388
+ }
1389
+ ],
1390
+ "url": {
1391
+ "raw": "{{baseUrl}}/auth/2fa/verify",
1392
+ "host": [
1393
+ "{{baseUrl}}"
1394
+ ],
1395
+ "path": [
1396
+ "auth",
1397
+ "2fa",
1398
+ "verify"
1399
+ ]
1400
+ },
1401
+ "body": {
1402
+ "mode": "raw",
1403
+ "raw": "{\n \"challengeToken\": \"{{challengeToken}}\",\n \"code\": \"{{totpCode}}\"\n}",
1404
+ "options": {
1405
+ "raw": {
1406
+ "language": "json"
1407
+ }
1408
+ }
1409
+ }
1410
+ }
1411
+ },
1412
+ {
1413
+ "name": "New backup codes",
1414
+ "event": [
1415
+ {
1416
+ "listen": "prerequest",
1417
+ "script": {
1418
+ "type": "text/javascript",
1419
+ "exec": [
1420
+ "pm.sendRequest(pm.variables.replaceIn(\"{{baseUrl}}/dev/api/totp?secret={{totpSecret}}\"), (error, response) => {",
1421
+ " if (error || response.code !== 200) { console.warn(\"Run \\\"Start 2FA setup\\\" first.\"); return; }",
1422
+ " pm.collectionVariables.set(\"totpCode\", response.json().code);",
1423
+ "});"
1424
+ ]
1425
+ }
1426
+ }
1427
+ ],
1428
+ "request": {
1429
+ "method": "POST",
1430
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1431
+ "header": [
1432
+ {
1433
+ "key": "Content-Type",
1434
+ "value": "application/json"
1435
+ }
1436
+ ],
1437
+ "url": {
1438
+ "raw": "{{baseUrl}}/auth/2fa/backup-codes",
1439
+ "host": [
1440
+ "{{baseUrl}}"
1441
+ ],
1442
+ "path": [
1443
+ "auth",
1444
+ "2fa",
1445
+ "backup-codes"
1446
+ ]
1447
+ },
1448
+ "body": {
1449
+ "mode": "raw",
1450
+ "raw": "{\n \"code\": \"{{totpCode}}\"\n}",
1451
+ "options": {
1452
+ "raw": {
1453
+ "language": "json"
1454
+ }
1455
+ }
1456
+ }
1457
+ }
1458
+ },
1459
+ {
1460
+ "name": "Disable 2FA",
1461
+ "event": [
1462
+ {
1463
+ "listen": "prerequest",
1464
+ "script": {
1465
+ "type": "text/javascript",
1466
+ "exec": [
1467
+ "pm.sendRequest(pm.variables.replaceIn(\"{{baseUrl}}/dev/api/totp?secret={{totpSecret}}\"), (error, response) => {",
1468
+ " if (error || response.code !== 200) { console.warn(\"Run \\\"Start 2FA setup\\\" first.\"); return; }",
1469
+ " pm.collectionVariables.set(\"totpCode\", response.json().code);",
1470
+ "});"
1471
+ ]
1472
+ }
1473
+ }
1474
+ ],
1475
+ "request": {
1476
+ "method": "POST",
1477
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1478
+ "header": [
1479
+ {
1480
+ "key": "Content-Type",
1481
+ "value": "application/json"
1482
+ }
1483
+ ],
1484
+ "url": {
1485
+ "raw": "{{baseUrl}}/auth/2fa/disable",
1486
+ "host": [
1487
+ "{{baseUrl}}"
1488
+ ],
1489
+ "path": [
1490
+ "auth",
1491
+ "2fa",
1492
+ "disable"
1493
+ ]
1494
+ },
1495
+ "body": {
1496
+ "mode": "raw",
1497
+ "raw": "{\n \"code\": \"{{totpCode}}\"\n}",
1498
+ "options": {
1499
+ "raw": {
1500
+ "language": "json"
1501
+ }
1502
+ }
1503
+ }
1504
+ }
1505
+ }
1506
+ ]
1507
+ },
1508
+ {
1509
+ "name": "5. Social sign-in",
1510
+ "item": [
1511
+ {
1512
+ "name": "Sign in with provider",
1513
+ "event": [
1514
+ {
1515
+ "listen": "test",
1516
+ "script": {
1517
+ "type": "text/javascript",
1518
+ "exec": [
1519
+ "const body = pm.response.json();",
1520
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
1521
+ "if (read(body, \"accessToken\") !== undefined) { pm.collectionVariables.set(\"accessToken\", read(body, \"accessToken\")); console.log(\"saved accessToken\"); }",
1522
+ "if (read(body, \"refreshToken\") !== undefined) { pm.collectionVariables.set(\"refreshToken\", read(body, \"refreshToken\")); console.log(\"saved refreshToken\"); }",
1523
+ "if (read(body, \"sessionId\") !== undefined) { pm.collectionVariables.set(\"sessionId\", read(body, \"sessionId\")); console.log(\"saved sessionId\"); }",
1524
+ "if (read(body, \"user.id\") !== undefined) { pm.collectionVariables.set(\"userId\", read(body, \"user.id\")); console.log(\"saved userId\"); }",
1525
+ "if (read(body, \"challengeToken\") !== undefined) { pm.collectionVariables.set(\"challengeToken\", read(body, \"challengeToken\")); console.log(\"saved challengeToken\"); }"
1526
+ ]
1527
+ }
1528
+ }
1529
+ ],
1530
+ "request": {
1531
+ "method": "POST",
1532
+ "description": "Easiest with the \"Sign in with Google\" button on the dev dashboard. In Postman, paste a real ID token into paste-the-provider-token-here.\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1533
+ "auth": {
1534
+ "type": "noauth"
1535
+ },
1536
+ "header": [
1537
+ {
1538
+ "key": "Content-Type",
1539
+ "value": "application/json"
1540
+ }
1541
+ ],
1542
+ "url": {
1543
+ "raw": "{{baseUrl}}/auth/social/{{provider}}",
1544
+ "host": [
1545
+ "{{baseUrl}}"
1546
+ ],
1547
+ "path": [
1548
+ "auth",
1549
+ "social",
1550
+ "{{provider}}"
1551
+ ]
1552
+ },
1553
+ "body": {
1554
+ "mode": "raw",
1555
+ "raw": "{\n \"token\": \"{{socialToken}}\",\n \"firstName\": \"Asha\",\n \"lastName\": \"Rao\",\n \"acceptTerms\": true,\n \"acceptPrivacyPolicy\": true\n}",
1556
+ "options": {
1557
+ "raw": {
1558
+ "language": "json"
1559
+ }
1560
+ }
1561
+ }
1562
+ }
1563
+ },
1564
+ {
1565
+ "name": "Link provider",
1566
+ "event": [],
1567
+ "request": {
1568
+ "method": "POST",
1569
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1570
+ "header": [
1571
+ {
1572
+ "key": "Content-Type",
1573
+ "value": "application/json"
1574
+ }
1575
+ ],
1576
+ "url": {
1577
+ "raw": "{{baseUrl}}/auth/social/{{provider}}/link",
1578
+ "host": [
1579
+ "{{baseUrl}}"
1580
+ ],
1581
+ "path": [
1582
+ "auth",
1583
+ "social",
1584
+ "{{provider}}",
1585
+ "link"
1586
+ ]
1587
+ },
1588
+ "body": {
1589
+ "mode": "raw",
1590
+ "raw": "{\n \"token\": \"{{socialToken}}\"\n}",
1591
+ "options": {
1592
+ "raw": {
1593
+ "language": "json"
1594
+ }
1595
+ }
1596
+ }
1597
+ }
1598
+ },
1599
+ {
1600
+ "name": "Unlink provider",
1601
+ "event": [],
1602
+ "request": {
1603
+ "method": "DELETE",
1604
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1605
+ "header": [],
1606
+ "url": {
1607
+ "raw": "{{baseUrl}}/auth/social/{{provider}}",
1608
+ "host": [
1609
+ "{{baseUrl}}"
1610
+ ],
1611
+ "path": [
1612
+ "auth",
1613
+ "social",
1614
+ "{{provider}}"
1615
+ ]
1616
+ }
1617
+ }
1618
+ }
1619
+ ]
1620
+ },
1621
+ {
1622
+ "name": "6. Passkeys",
1623
+ "item": [
1624
+ {
1625
+ "name": "Registration options",
1626
+ "event": [],
1627
+ "request": {
1628
+ "method": "POST",
1629
+ "description": "Passkeys need a browser or phone: use the Passkeys panel on the dev dashboard. These requests show the raw options.\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1630
+ "header": [],
1631
+ "url": {
1632
+ "raw": "{{baseUrl}}/auth/passkeys/register/options",
1633
+ "host": [
1634
+ "{{baseUrl}}"
1635
+ ],
1636
+ "path": [
1637
+ "auth",
1638
+ "passkeys",
1639
+ "register",
1640
+ "options"
1641
+ ]
1642
+ }
1643
+ }
1644
+ },
1645
+ {
1646
+ "name": "Sign-in options",
1647
+ "event": [],
1648
+ "request": {
1649
+ "method": "POST",
1650
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1651
+ "auth": {
1652
+ "type": "noauth"
1653
+ },
1654
+ "header": [],
1655
+ "url": {
1656
+ "raw": "{{baseUrl}}/auth/passkeys/sign-in/options",
1657
+ "host": [
1658
+ "{{baseUrl}}"
1659
+ ],
1660
+ "path": [
1661
+ "auth",
1662
+ "passkeys",
1663
+ "sign-in",
1664
+ "options"
1665
+ ]
1666
+ }
1667
+ }
1668
+ },
1669
+ {
1670
+ "name": "Register passkey (from browser response)",
1671
+ "event": [],
1672
+ "request": {
1673
+ "method": "POST",
1674
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1675
+ "header": [
1676
+ {
1677
+ "key": "Content-Type",
1678
+ "value": "application/json"
1679
+ }
1680
+ ],
1681
+ "url": {
1682
+ "raw": "{{baseUrl}}/auth/passkeys/register/verify",
1683
+ "host": [
1684
+ "{{baseUrl}}"
1685
+ ],
1686
+ "path": [
1687
+ "auth",
1688
+ "passkeys",
1689
+ "register",
1690
+ "verify"
1691
+ ]
1692
+ },
1693
+ "body": {
1694
+ "mode": "raw",
1695
+ "raw": "{\n \"challengeToken\": \"{{challengeToken}}\",\n \"name\": \"My laptop\",\n \"response\": {}\n}",
1696
+ "options": {
1697
+ "raw": {
1698
+ "language": "json"
1699
+ }
1700
+ }
1701
+ }
1702
+ }
1703
+ },
1704
+ {
1705
+ "name": "Sign in with passkey (from browser response)",
1706
+ "event": [],
1707
+ "request": {
1708
+ "method": "POST",
1709
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1710
+ "auth": {
1711
+ "type": "noauth"
1712
+ },
1713
+ "header": [
1714
+ {
1715
+ "key": "Content-Type",
1716
+ "value": "application/json"
1717
+ }
1718
+ ],
1719
+ "url": {
1720
+ "raw": "{{baseUrl}}/auth/passkeys/sign-in/verify",
1721
+ "host": [
1722
+ "{{baseUrl}}"
1723
+ ],
1724
+ "path": [
1725
+ "auth",
1726
+ "passkeys",
1727
+ "sign-in",
1728
+ "verify"
1729
+ ]
1730
+ },
1731
+ "body": {
1732
+ "mode": "raw",
1733
+ "raw": "{\n \"challengeToken\": \"{{challengeToken}}\",\n \"response\": {}\n}",
1734
+ "options": {
1735
+ "raw": {
1736
+ "language": "json"
1737
+ }
1738
+ }
1739
+ }
1740
+ }
1741
+ },
1742
+ {
1743
+ "name": "List my passkeys",
1744
+ "event": [
1745
+ {
1746
+ "listen": "test",
1747
+ "script": {
1748
+ "type": "text/javascript",
1749
+ "exec": [
1750
+ "const body = pm.response.json();",
1751
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
1752
+ "if (read(body, \"passkeys.0.id\") !== undefined) { pm.collectionVariables.set(\"passkeyId\", read(body, \"passkeys.0.id\")); console.log(\"saved passkeyId\"); }"
1753
+ ]
1754
+ }
1755
+ }
1756
+ ],
1757
+ "request": {
1758
+ "method": "GET",
1759
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1760
+ "header": [],
1761
+ "url": {
1762
+ "raw": "{{baseUrl}}/auth/passkeys",
1763
+ "host": [
1764
+ "{{baseUrl}}"
1765
+ ],
1766
+ "path": [
1767
+ "auth",
1768
+ "passkeys"
1769
+ ]
1770
+ }
1771
+ }
1772
+ },
1773
+ {
1774
+ "name": "Rename passkey",
1775
+ "event": [],
1776
+ "request": {
1777
+ "method": "PATCH",
1778
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1779
+ "header": [
1780
+ {
1781
+ "key": "Content-Type",
1782
+ "value": "application/json"
1783
+ }
1784
+ ],
1785
+ "url": {
1786
+ "raw": "{{baseUrl}}/auth/passkeys/{{passkeyId}}",
1787
+ "host": [
1788
+ "{{baseUrl}}"
1789
+ ],
1790
+ "path": [
1791
+ "auth",
1792
+ "passkeys",
1793
+ "{{passkeyId}}"
1794
+ ]
1795
+ },
1796
+ "body": {
1797
+ "mode": "raw",
1798
+ "raw": "{\n \"name\": \"Work laptop\"\n}",
1799
+ "options": {
1800
+ "raw": {
1801
+ "language": "json"
1802
+ }
1803
+ }
1804
+ }
1805
+ }
1806
+ },
1807
+ {
1808
+ "name": "Remove passkey",
1809
+ "event": [],
1810
+ "request": {
1811
+ "method": "DELETE",
1812
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1813
+ "header": [],
1814
+ "url": {
1815
+ "raw": "{{baseUrl}}/auth/passkeys/{{passkeyId}}",
1816
+ "host": [
1817
+ "{{baseUrl}}"
1818
+ ],
1819
+ "path": [
1820
+ "auth",
1821
+ "passkeys",
1822
+ "{{passkeyId}}"
1823
+ ]
1824
+ }
1825
+ }
1826
+ }
1827
+ ]
1828
+ },
1829
+ {
1830
+ "name": "7. Organizations",
1831
+ "item": [
1832
+ {
1833
+ "name": "Create organization",
1834
+ "event": [
1835
+ {
1836
+ "listen": "test",
1837
+ "script": {
1838
+ "type": "text/javascript",
1839
+ "exec": [
1840
+ "const body = pm.response.json();",
1841
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
1842
+ "if (read(body, \"organization.id\") !== undefined) { pm.collectionVariables.set(\"organizationId\", read(body, \"organization.id\")); console.log(\"saved organizationId\"); }"
1843
+ ]
1844
+ }
1845
+ }
1846
+ ],
1847
+ "request": {
1848
+ "method": "POST",
1849
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1850
+ "header": [
1851
+ {
1852
+ "key": "Content-Type",
1853
+ "value": "application/json"
1854
+ }
1855
+ ],
1856
+ "url": {
1857
+ "raw": "{{baseUrl}}/auth/organizations",
1858
+ "host": [
1859
+ "{{baseUrl}}"
1860
+ ],
1861
+ "path": [
1862
+ "auth",
1863
+ "organizations"
1864
+ ]
1865
+ },
1866
+ "body": {
1867
+ "mode": "raw",
1868
+ "raw": "{\n \"name\": \"Acme Travels\",\n \"slug\": \"{{organizationSlug}}\"\n}",
1869
+ "options": {
1870
+ "raw": {
1871
+ "language": "json"
1872
+ }
1873
+ }
1874
+ }
1875
+ }
1876
+ },
1877
+ {
1878
+ "name": "My organizations",
1879
+ "event": [],
1880
+ "request": {
1881
+ "method": "GET",
1882
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1883
+ "header": [],
1884
+ "url": {
1885
+ "raw": "{{baseUrl}}/auth/organizations",
1886
+ "host": [
1887
+ "{{baseUrl}}"
1888
+ ],
1889
+ "path": [
1890
+ "auth",
1891
+ "organizations"
1892
+ ]
1893
+ }
1894
+ }
1895
+ },
1896
+ {
1897
+ "name": "Get organization",
1898
+ "event": [],
1899
+ "request": {
1900
+ "method": "GET",
1901
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1902
+ "header": [],
1903
+ "url": {
1904
+ "raw": "{{baseUrl}}/auth/organizations/{{organizationId}}",
1905
+ "host": [
1906
+ "{{baseUrl}}"
1907
+ ],
1908
+ "path": [
1909
+ "auth",
1910
+ "organizations",
1911
+ "{{organizationId}}"
1912
+ ]
1913
+ }
1914
+ }
1915
+ },
1916
+ {
1917
+ "name": "Update organization",
1918
+ "event": [],
1919
+ "request": {
1920
+ "method": "PATCH",
1921
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1922
+ "header": [
1923
+ {
1924
+ "key": "Content-Type",
1925
+ "value": "application/json"
1926
+ }
1927
+ ],
1928
+ "url": {
1929
+ "raw": "{{baseUrl}}/auth/organizations/{{organizationId}}",
1930
+ "host": [
1931
+ "{{baseUrl}}"
1932
+ ],
1933
+ "path": [
1934
+ "auth",
1935
+ "organizations",
1936
+ "{{organizationId}}"
1937
+ ]
1938
+ },
1939
+ "body": {
1940
+ "mode": "raw",
1941
+ "raw": "{\n \"name\": \"Acme Travels India\",\n \"metadata\": {\n \"city\": \"Bengaluru\"\n }\n}",
1942
+ "options": {
1943
+ "raw": {
1944
+ "language": "json"
1945
+ }
1946
+ }
1947
+ }
1948
+ }
1949
+ },
1950
+ {
1951
+ "name": "Invite member",
1952
+ "event": [],
1953
+ "request": {
1954
+ "method": "POST",
1955
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
1956
+ "header": [
1957
+ {
1958
+ "key": "Content-Type",
1959
+ "value": "application/json"
1960
+ }
1961
+ ],
1962
+ "url": {
1963
+ "raw": "{{baseUrl}}/auth/organizations/{{organizationId}}/invitations",
1964
+ "host": [
1965
+ "{{baseUrl}}"
1966
+ ],
1967
+ "path": [
1968
+ "auth",
1969
+ "organizations",
1970
+ "{{organizationId}}",
1971
+ "invitations"
1972
+ ]
1973
+ },
1974
+ "body": {
1975
+ "mode": "raw",
1976
+ "raw": "{\n \"email\": \"{{secondEmail}}\",\n \"role\": \"member\"\n}",
1977
+ "options": {
1978
+ "raw": {
1979
+ "language": "json"
1980
+ }
1981
+ }
1982
+ }
1983
+ }
1984
+ },
1985
+ {
1986
+ "name": "List invitations",
1987
+ "event": [
1988
+ {
1989
+ "listen": "test",
1990
+ "script": {
1991
+ "type": "text/javascript",
1992
+ "exec": [
1993
+ "const body = pm.response.json();",
1994
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
1995
+ "if (read(body, \"invitations.0.id\") !== undefined) { pm.collectionVariables.set(\"invitationId\", read(body, \"invitations.0.id\")); console.log(\"saved invitationId\"); }"
1996
+ ]
1997
+ }
1998
+ }
1999
+ ],
2000
+ "request": {
2001
+ "method": "GET",
2002
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2003
+ "header": [],
2004
+ "url": {
2005
+ "raw": "{{baseUrl}}/auth/organizations/{{organizationId}}/invitations",
2006
+ "host": [
2007
+ "{{baseUrl}}"
2008
+ ],
2009
+ "path": [
2010
+ "auth",
2011
+ "organizations",
2012
+ "{{organizationId}}",
2013
+ "invitations"
2014
+ ]
2015
+ }
2016
+ }
2017
+ },
2018
+ {
2019
+ "name": "Accept invitation (as invited user)",
2020
+ "event": [
2021
+ {
2022
+ "listen": "prerequest",
2023
+ "script": {
2024
+ "type": "text/javascript",
2025
+ "exec": [
2026
+ "const to = pm.variables.replaceIn(\"{{secondEmail}}\");",
2027
+ "pm.sendRequest(pm.variables.replaceIn(\"{{baseUrl}}\") + \"/dev/api/inbox/latest?to=\" + encodeURIComponent(to) + \"&type=organization_invitation\", (error, response) => {",
2028
+ " if (error || response.code !== 200) { console.warn(\"No message in the dev inbox yet: send it first.\"); return; }",
2029
+ " pm.collectionVariables.set(\"invitationToken\", response.json().token);",
2030
+ " console.log(\"invitationToken taken from the dev inbox\");",
2031
+ "});"
2032
+ ]
2033
+ }
2034
+ }
2035
+ ],
2036
+ "request": {
2037
+ "method": "POST",
2038
+ "description": "Sign in as ravi@example.com first (e.g. \"Passwordless > Verify email code\"), so the access token is theirs.\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2039
+ "header": [
2040
+ {
2041
+ "key": "Content-Type",
2042
+ "value": "application/json"
2043
+ }
2044
+ ],
2045
+ "url": {
2046
+ "raw": "{{baseUrl}}/auth/organizations/invitations/accept",
2047
+ "host": [
2048
+ "{{baseUrl}}"
2049
+ ],
2050
+ "path": [
2051
+ "auth",
2052
+ "organizations",
2053
+ "invitations",
2054
+ "accept"
2055
+ ]
2056
+ },
2057
+ "body": {
2058
+ "mode": "raw",
2059
+ "raw": "{\n \"token\": \"{{invitationToken}}\"\n}",
2060
+ "options": {
2061
+ "raw": {
2062
+ "language": "json"
2063
+ }
2064
+ }
2065
+ }
2066
+ }
2067
+ },
2068
+ {
2069
+ "name": "List members",
2070
+ "event": [
2071
+ {
2072
+ "listen": "test",
2073
+ "script": {
2074
+ "type": "text/javascript",
2075
+ "exec": [
2076
+ "const body = pm.response.json();",
2077
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
2078
+ "if (read(body, \"members.1.userId\") !== undefined) { pm.collectionVariables.set(\"memberUserId\", read(body, \"members.1.userId\")); console.log(\"saved memberUserId\"); }"
2079
+ ]
2080
+ }
2081
+ }
2082
+ ],
2083
+ "request": {
2084
+ "method": "GET",
2085
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2086
+ "header": [],
2087
+ "url": {
2088
+ "raw": "{{baseUrl}}/auth/organizations/{{organizationId}}/members",
2089
+ "host": [
2090
+ "{{baseUrl}}"
2091
+ ],
2092
+ "path": [
2093
+ "auth",
2094
+ "organizations",
2095
+ "{{organizationId}}",
2096
+ "members"
2097
+ ]
2098
+ }
2099
+ }
2100
+ },
2101
+ {
2102
+ "name": "Change member role",
2103
+ "event": [],
2104
+ "request": {
2105
+ "method": "PATCH",
2106
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2107
+ "header": [
2108
+ {
2109
+ "key": "Content-Type",
2110
+ "value": "application/json"
2111
+ }
2112
+ ],
2113
+ "url": {
2114
+ "raw": "{{baseUrl}}/auth/organizations/{{organizationId}}/members/{{memberUserId}}",
2115
+ "host": [
2116
+ "{{baseUrl}}"
2117
+ ],
2118
+ "path": [
2119
+ "auth",
2120
+ "organizations",
2121
+ "{{organizationId}}",
2122
+ "members",
2123
+ "{{memberUserId}}"
2124
+ ]
2125
+ },
2126
+ "body": {
2127
+ "mode": "raw",
2128
+ "raw": "{\n \"role\": \"admin\"\n}",
2129
+ "options": {
2130
+ "raw": {
2131
+ "language": "json"
2132
+ }
2133
+ }
2134
+ }
2135
+ }
2136
+ },
2137
+ {
2138
+ "name": "Remove member",
2139
+ "event": [],
2140
+ "request": {
2141
+ "method": "DELETE",
2142
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2143
+ "header": [],
2144
+ "url": {
2145
+ "raw": "{{baseUrl}}/auth/organizations/{{organizationId}}/members/{{memberUserId}}",
2146
+ "host": [
2147
+ "{{baseUrl}}"
2148
+ ],
2149
+ "path": [
2150
+ "auth",
2151
+ "organizations",
2152
+ "{{organizationId}}",
2153
+ "members",
2154
+ "{{memberUserId}}"
2155
+ ]
2156
+ }
2157
+ }
2158
+ },
2159
+ {
2160
+ "name": "Cancel invitation",
2161
+ "event": [],
2162
+ "request": {
2163
+ "method": "DELETE",
2164
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2165
+ "header": [],
2166
+ "url": {
2167
+ "raw": "{{baseUrl}}/auth/organizations/{{organizationId}}/invitations/{{invitationId}}",
2168
+ "host": [
2169
+ "{{baseUrl}}"
2170
+ ],
2171
+ "path": [
2172
+ "auth",
2173
+ "organizations",
2174
+ "{{organizationId}}",
2175
+ "invitations",
2176
+ "{{invitationId}}"
2177
+ ]
2178
+ }
2179
+ }
2180
+ },
2181
+ {
2182
+ "name": "Switch active organization",
2183
+ "event": [
2184
+ {
2185
+ "listen": "test",
2186
+ "script": {
2187
+ "type": "text/javascript",
2188
+ "exec": [
2189
+ "const body = pm.response.json();",
2190
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
2191
+ "if (read(body, \"accessToken\") !== undefined) { pm.collectionVariables.set(\"accessToken\", read(body, \"accessToken\")); console.log(\"saved accessToken\"); }"
2192
+ ]
2193
+ }
2194
+ }
2195
+ ],
2196
+ "request": {
2197
+ "method": "POST",
2198
+ "description": "The new access token carries org_id and org_role (decode it at jwt.io to see).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2199
+ "header": [
2200
+ {
2201
+ "key": "Content-Type",
2202
+ "value": "application/json"
2203
+ }
2204
+ ],
2205
+ "url": {
2206
+ "raw": "{{baseUrl}}/auth/organizations/switch",
2207
+ "host": [
2208
+ "{{baseUrl}}"
2209
+ ],
2210
+ "path": [
2211
+ "auth",
2212
+ "organizations",
2213
+ "switch"
2214
+ ]
2215
+ },
2216
+ "body": {
2217
+ "mode": "raw",
2218
+ "raw": "{\n \"organizationId\": \"{{organizationId}}\"\n}",
2219
+ "options": {
2220
+ "raw": {
2221
+ "language": "json"
2222
+ }
2223
+ }
2224
+ }
2225
+ }
2226
+ },
2227
+ {
2228
+ "name": "Delete organization",
2229
+ "event": [],
2230
+ "request": {
2231
+ "method": "DELETE",
2232
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2233
+ "header": [],
2234
+ "url": {
2235
+ "raw": "{{baseUrl}}/auth/organizations/{{organizationId}}",
2236
+ "host": [
2237
+ "{{baseUrl}}"
2238
+ ],
2239
+ "path": [
2240
+ "auth",
2241
+ "organizations",
2242
+ "{{organizationId}}"
2243
+ ]
2244
+ }
2245
+ }
2246
+ }
2247
+ ]
2248
+ },
2249
+ {
2250
+ "name": "8. Admin",
2251
+ "item": [
2252
+ {
2253
+ "name": "Search users",
2254
+ "event": [],
2255
+ "request": {
2256
+ "method": "GET",
2257
+ "description": "Make yourself admin first: dev dashboard > \"Make admin\", then Login again.\n\nRequires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2258
+ "header": [],
2259
+ "url": {
2260
+ "raw": "{{baseUrl}}/auth/admin/users?search=example.com&page=1&pageSize=20",
2261
+ "host": [
2262
+ "{{baseUrl}}"
2263
+ ],
2264
+ "path": [
2265
+ "auth",
2266
+ "admin",
2267
+ "users"
2268
+ ],
2269
+ "query": [
2270
+ {
2271
+ "key": "search",
2272
+ "value": "example.com"
2273
+ },
2274
+ {
2275
+ "key": "page",
2276
+ "value": "1"
2277
+ },
2278
+ {
2279
+ "key": "pageSize",
2280
+ "value": "20"
2281
+ }
2282
+ ]
2283
+ }
2284
+ }
2285
+ },
2286
+ {
2287
+ "name": "Get user details",
2288
+ "event": [],
2289
+ "request": {
2290
+ "method": "GET",
2291
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2292
+ "header": [],
2293
+ "url": {
2294
+ "raw": "{{baseUrl}}/auth/admin/users/{{userId}}",
2295
+ "host": [
2296
+ "{{baseUrl}}"
2297
+ ],
2298
+ "path": [
2299
+ "auth",
2300
+ "admin",
2301
+ "users",
2302
+ "{{userId}}"
2303
+ ]
2304
+ }
2305
+ }
2306
+ },
2307
+ {
2308
+ "name": "Update user",
2309
+ "event": [],
2310
+ "request": {
2311
+ "method": "PATCH",
2312
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2313
+ "header": [
2314
+ {
2315
+ "key": "Content-Type",
2316
+ "value": "application/json"
2317
+ }
2318
+ ],
2319
+ "url": {
2320
+ "raw": "{{baseUrl}}/auth/admin/users/{{userId}}",
2321
+ "host": [
2322
+ "{{baseUrl}}"
2323
+ ],
2324
+ "path": [
2325
+ "auth",
2326
+ "admin",
2327
+ "users",
2328
+ "{{userId}}"
2329
+ ]
2330
+ },
2331
+ "body": {
2332
+ "mode": "raw",
2333
+ "raw": "{\n \"metadata\": {\n \"kycStatus\": \"approved\"\n }\n}",
2334
+ "options": {
2335
+ "raw": {
2336
+ "language": "json"
2337
+ }
2338
+ }
2339
+ }
2340
+ }
2341
+ },
2342
+ {
2343
+ "name": "Set roles",
2344
+ "event": [],
2345
+ "request": {
2346
+ "method": "PUT",
2347
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2348
+ "header": [
2349
+ {
2350
+ "key": "Content-Type",
2351
+ "value": "application/json"
2352
+ }
2353
+ ],
2354
+ "url": {
2355
+ "raw": "{{baseUrl}}/auth/admin/users/{{userId}}/roles",
2356
+ "host": [
2357
+ "{{baseUrl}}"
2358
+ ],
2359
+ "path": [
2360
+ "auth",
2361
+ "admin",
2362
+ "users",
2363
+ "{{userId}}",
2364
+ "roles"
2365
+ ]
2366
+ },
2367
+ "body": {
2368
+ "mode": "raw",
2369
+ "raw": "{\n \"roles\": [\n \"user\",\n \"admin\"\n ]\n}",
2370
+ "options": {
2371
+ "raw": {
2372
+ "language": "json"
2373
+ }
2374
+ }
2375
+ }
2376
+ }
2377
+ },
2378
+ {
2379
+ "name": "Suspend user",
2380
+ "event": [],
2381
+ "request": {
2382
+ "method": "POST",
2383
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2384
+ "header": [
2385
+ {
2386
+ "key": "Content-Type",
2387
+ "value": "application/json"
2388
+ }
2389
+ ],
2390
+ "url": {
2391
+ "raw": "{{baseUrl}}/auth/admin/users/{{userId}}/suspend",
2392
+ "host": [
2393
+ "{{baseUrl}}"
2394
+ ],
2395
+ "path": [
2396
+ "auth",
2397
+ "admin",
2398
+ "users",
2399
+ "{{userId}}",
2400
+ "suspend"
2401
+ ]
2402
+ },
2403
+ "body": {
2404
+ "mode": "raw",
2405
+ "raw": "{\n \"reason\": \"Manual test\"\n}",
2406
+ "options": {
2407
+ "raw": {
2408
+ "language": "json"
2409
+ }
2410
+ }
2411
+ }
2412
+ }
2413
+ },
2414
+ {
2415
+ "name": "Unsuspend user",
2416
+ "event": [],
2417
+ "request": {
2418
+ "method": "POST",
2419
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2420
+ "header": [],
2421
+ "url": {
2422
+ "raw": "{{baseUrl}}/auth/admin/users/{{userId}}/unsuspend",
2423
+ "host": [
2424
+ "{{baseUrl}}"
2425
+ ],
2426
+ "path": [
2427
+ "auth",
2428
+ "admin",
2429
+ "users",
2430
+ "{{userId}}",
2431
+ "unsuspend"
2432
+ ]
2433
+ }
2434
+ }
2435
+ },
2436
+ {
2437
+ "name": "Verify user email",
2438
+ "event": [],
2439
+ "request": {
2440
+ "method": "POST",
2441
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2442
+ "header": [],
2443
+ "url": {
2444
+ "raw": "{{baseUrl}}/auth/admin/users/{{userId}}/verify-email",
2445
+ "host": [
2446
+ "{{baseUrl}}"
2447
+ ],
2448
+ "path": [
2449
+ "auth",
2450
+ "admin",
2451
+ "users",
2452
+ "{{userId}}",
2453
+ "verify-email"
2454
+ ]
2455
+ }
2456
+ }
2457
+ },
2458
+ {
2459
+ "name": "Reset user 2FA",
2460
+ "event": [],
2461
+ "request": {
2462
+ "method": "POST",
2463
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2464
+ "header": [],
2465
+ "url": {
2466
+ "raw": "{{baseUrl}}/auth/admin/users/{{userId}}/reset-2fa",
2467
+ "host": [
2468
+ "{{baseUrl}}"
2469
+ ],
2470
+ "path": [
2471
+ "auth",
2472
+ "admin",
2473
+ "users",
2474
+ "{{userId}}",
2475
+ "reset-2fa"
2476
+ ]
2477
+ }
2478
+ }
2479
+ },
2480
+ {
2481
+ "name": "Sign user out everywhere",
2482
+ "event": [],
2483
+ "request": {
2484
+ "method": "POST",
2485
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2486
+ "header": [],
2487
+ "url": {
2488
+ "raw": "{{baseUrl}}/auth/admin/users/{{userId}}/logout-all",
2489
+ "host": [
2490
+ "{{baseUrl}}"
2491
+ ],
2492
+ "path": [
2493
+ "auth",
2494
+ "admin",
2495
+ "users",
2496
+ "{{userId}}",
2497
+ "logout-all"
2498
+ ]
2499
+ }
2500
+ }
2501
+ },
2502
+ {
2503
+ "name": "Delete user",
2504
+ "event": [],
2505
+ "request": {
2506
+ "method": "DELETE",
2507
+ "description": "Uses <userId>: careful, that is you unless you change it.\n\nRequires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2508
+ "header": [],
2509
+ "url": {
2510
+ "raw": "{{baseUrl}}/auth/admin/users/{{userId}}",
2511
+ "host": [
2512
+ "{{baseUrl}}"
2513
+ ],
2514
+ "path": [
2515
+ "auth",
2516
+ "admin",
2517
+ "users",
2518
+ "{{userId}}"
2519
+ ]
2520
+ }
2521
+ }
2522
+ },
2523
+ {
2524
+ "name": "Get settings",
2525
+ "event": [],
2526
+ "request": {
2527
+ "method": "GET",
2528
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2529
+ "header": [],
2530
+ "url": {
2531
+ "raw": "{{baseUrl}}/auth/admin/settings",
2532
+ "host": [
2533
+ "{{baseUrl}}"
2534
+ ],
2535
+ "path": [
2536
+ "auth",
2537
+ "admin",
2538
+ "settings"
2539
+ ]
2540
+ }
2541
+ }
2542
+ },
2543
+ {
2544
+ "name": "Change settings",
2545
+ "event": [],
2546
+ "request": {
2547
+ "method": "PATCH",
2548
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2549
+ "header": [
2550
+ {
2551
+ "key": "Content-Type",
2552
+ "value": "application/json"
2553
+ }
2554
+ ],
2555
+ "url": {
2556
+ "raw": "{{baseUrl}}/auth/admin/settings",
2557
+ "host": [
2558
+ "{{baseUrl}}"
2559
+ ],
2560
+ "path": [
2561
+ "auth",
2562
+ "admin",
2563
+ "settings"
2564
+ ]
2565
+ },
2566
+ "body": {
2567
+ "mode": "raw",
2568
+ "raw": "{\n \"magicLink\": {\n \"enabled\": true\n },\n \"security\": {\n \"notifyOnNewSignIn\": true\n }\n}",
2569
+ "options": {
2570
+ "raw": {
2571
+ "language": "json"
2572
+ }
2573
+ }
2574
+ }
2575
+ }
2576
+ },
2577
+ {
2578
+ "name": "Reset settings to code defaults",
2579
+ "event": [],
2580
+ "request": {
2581
+ "method": "DELETE",
2582
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2583
+ "header": [],
2584
+ "url": {
2585
+ "raw": "{{baseUrl}}/auth/admin/settings",
2586
+ "host": [
2587
+ "{{baseUrl}}"
2588
+ ],
2589
+ "path": [
2590
+ "auth",
2591
+ "admin",
2592
+ "settings"
2593
+ ]
2594
+ }
2595
+ }
2596
+ },
2597
+ {
2598
+ "name": "Audit log",
2599
+ "event": [],
2600
+ "request": {
2601
+ "method": "GET",
2602
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2603
+ "header": [],
2604
+ "url": {
2605
+ "raw": "{{baseUrl}}/auth/admin/audit-log?page=1&pageSize=20",
2606
+ "host": [
2607
+ "{{baseUrl}}"
2608
+ ],
2609
+ "path": [
2610
+ "auth",
2611
+ "admin",
2612
+ "audit-log"
2613
+ ],
2614
+ "query": [
2615
+ {
2616
+ "key": "page",
2617
+ "value": "1"
2618
+ },
2619
+ {
2620
+ "key": "pageSize",
2621
+ "value": "20"
2622
+ }
2623
+ ]
2624
+ }
2625
+ }
2626
+ },
2627
+ {
2628
+ "name": "Stats",
2629
+ "event": [],
2630
+ "request": {
2631
+ "method": "GET",
2632
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2633
+ "header": [],
2634
+ "url": {
2635
+ "raw": "{{baseUrl}}/auth/admin/stats",
2636
+ "host": [
2637
+ "{{baseUrl}}"
2638
+ ],
2639
+ "path": [
2640
+ "auth",
2641
+ "admin",
2642
+ "stats"
2643
+ ]
2644
+ }
2645
+ }
2646
+ },
2647
+ {
2648
+ "name": "Run data cleanup now",
2649
+ "event": [],
2650
+ "request": {
2651
+ "method": "POST",
2652
+ "description": "Deletes rows older than settings.retention allows (it also runs every hour). Returns how many rows each step removed.\n\nRequires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2653
+ "header": [],
2654
+ "url": {
2655
+ "raw": "{{baseUrl}}/auth/admin/maintenance/cleanup",
2656
+ "host": [
2657
+ "{{baseUrl}}"
2658
+ ],
2659
+ "path": [
2660
+ "auth",
2661
+ "admin",
2662
+ "maintenance",
2663
+ "cleanup"
2664
+ ]
2665
+ }
2666
+ }
2667
+ },
2668
+ {
2669
+ "name": "Rotate signing key",
2670
+ "event": [],
2671
+ "request": {
2672
+ "method": "POST",
2673
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2674
+ "header": [],
2675
+ "url": {
2676
+ "raw": "{{baseUrl}}/auth/admin/signing-keys/rotate",
2677
+ "host": [
2678
+ "{{baseUrl}}"
2679
+ ],
2680
+ "path": [
2681
+ "auth",
2682
+ "admin",
2683
+ "signing-keys",
2684
+ "rotate"
2685
+ ]
2686
+ }
2687
+ }
2688
+ },
2689
+ {
2690
+ "name": "Create API key",
2691
+ "event": [
2692
+ {
2693
+ "listen": "test",
2694
+ "script": {
2695
+ "type": "text/javascript",
2696
+ "exec": [
2697
+ "const body = pm.response.json();",
2698
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
2699
+ "if (read(body, \"apiKey\") !== undefined) { pm.collectionVariables.set(\"apiKey\", read(body, \"apiKey\")); console.log(\"saved apiKey\"); }",
2700
+ "if (read(body, \"details.id\") !== undefined) { pm.collectionVariables.set(\"apiKeyId\", read(body, \"details.id\")); console.log(\"saved apiKeyId\"); }"
2701
+ ]
2702
+ }
2703
+ }
2704
+ ],
2705
+ "request": {
2706
+ "method": "POST",
2707
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2708
+ "header": [
2709
+ {
2710
+ "key": "Content-Type",
2711
+ "value": "application/json"
2712
+ }
2713
+ ],
2714
+ "url": {
2715
+ "raw": "{{baseUrl}}/auth/admin/api-keys",
2716
+ "host": [
2717
+ "{{baseUrl}}"
2718
+ ],
2719
+ "path": [
2720
+ "auth",
2721
+ "admin",
2722
+ "api-keys"
2723
+ ]
2724
+ },
2725
+ "body": {
2726
+ "mode": "raw",
2727
+ "raw": "{\n \"name\": \"Postman test key\",\n \"scopes\": [\n \"rides:read\"\n ]\n}",
2728
+ "options": {
2729
+ "raw": {
2730
+ "language": "json"
2731
+ }
2732
+ }
2733
+ }
2734
+ }
2735
+ },
2736
+ {
2737
+ "name": "List API keys",
2738
+ "event": [],
2739
+ "request": {
2740
+ "method": "GET",
2741
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2742
+ "header": [],
2743
+ "url": {
2744
+ "raw": "{{baseUrl}}/auth/admin/api-keys",
2745
+ "host": [
2746
+ "{{baseUrl}}"
2747
+ ],
2748
+ "path": [
2749
+ "auth",
2750
+ "admin",
2751
+ "api-keys"
2752
+ ]
2753
+ }
2754
+ }
2755
+ },
2756
+ {
2757
+ "name": "Revoke API key",
2758
+ "event": [],
2759
+ "request": {
2760
+ "method": "DELETE",
2761
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2762
+ "header": [],
2763
+ "url": {
2764
+ "raw": "{{baseUrl}}/auth/admin/api-keys/{{apiKeyId}}",
2765
+ "host": [
2766
+ "{{baseUrl}}"
2767
+ ],
2768
+ "path": [
2769
+ "auth",
2770
+ "admin",
2771
+ "api-keys",
2772
+ "{{apiKeyId}}"
2773
+ ]
2774
+ }
2775
+ }
2776
+ },
2777
+ {
2778
+ "name": "Create webhook (to the playground receiver)",
2779
+ "event": [
2780
+ {
2781
+ "listen": "test",
2782
+ "script": {
2783
+ "type": "text/javascript",
2784
+ "exec": [
2785
+ "const body = pm.response.json();",
2786
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
2787
+ "if (read(body, \"webhook.id\") !== undefined) { pm.collectionVariables.set(\"webhookId\", read(body, \"webhook.id\")); console.log(\"saved webhookId\"); }",
2788
+ "if (read(body, \"signingSecret\") !== undefined) { pm.collectionVariables.set(\"webhookSecret\", read(body, \"signingSecret\")); console.log(\"saved webhookSecret\"); }"
2789
+ ]
2790
+ }
2791
+ }
2792
+ ],
2793
+ "request": {
2794
+ "method": "POST",
2795
+ "description": "Deliveries appear on the dev dashboard with their signature check result.\n\nRequires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2796
+ "header": [
2797
+ {
2798
+ "key": "Content-Type",
2799
+ "value": "application/json"
2800
+ }
2801
+ ],
2802
+ "url": {
2803
+ "raw": "{{baseUrl}}/auth/admin/webhooks",
2804
+ "host": [
2805
+ "{{baseUrl}}"
2806
+ ],
2807
+ "path": [
2808
+ "auth",
2809
+ "admin",
2810
+ "webhooks"
2811
+ ]
2812
+ },
2813
+ "body": {
2814
+ "mode": "raw",
2815
+ "raw": "{\n \"url\": \"{{baseUrl}}/dev/webhook-receiver\",\n \"eventNames\": [],\n \"description\": \"Playground receiver\"\n}",
2816
+ "options": {
2817
+ "raw": {
2818
+ "language": "json"
2819
+ }
2820
+ }
2821
+ }
2822
+ }
2823
+ },
2824
+ {
2825
+ "name": "List webhooks",
2826
+ "event": [],
2827
+ "request": {
2828
+ "method": "GET",
2829
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2830
+ "header": [],
2831
+ "url": {
2832
+ "raw": "{{baseUrl}}/auth/admin/webhooks",
2833
+ "host": [
2834
+ "{{baseUrl}}"
2835
+ ],
2836
+ "path": [
2837
+ "auth",
2838
+ "admin",
2839
+ "webhooks"
2840
+ ]
2841
+ }
2842
+ }
2843
+ },
2844
+ {
2845
+ "name": "Update webhook",
2846
+ "event": [],
2847
+ "request": {
2848
+ "method": "PATCH",
2849
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2850
+ "header": [
2851
+ {
2852
+ "key": "Content-Type",
2853
+ "value": "application/json"
2854
+ }
2855
+ ],
2856
+ "url": {
2857
+ "raw": "{{baseUrl}}/auth/admin/webhooks/{{webhookId}}",
2858
+ "host": [
2859
+ "{{baseUrl}}"
2860
+ ],
2861
+ "path": [
2862
+ "auth",
2863
+ "admin",
2864
+ "webhooks",
2865
+ "{{webhookId}}"
2866
+ ]
2867
+ },
2868
+ "body": {
2869
+ "mode": "raw",
2870
+ "raw": "{\n \"eventNames\": [\n \"user.signed_in\",\n \"user.created\"\n ]\n}",
2871
+ "options": {
2872
+ "raw": {
2873
+ "language": "json"
2874
+ }
2875
+ }
2876
+ }
2877
+ }
2878
+ },
2879
+ {
2880
+ "name": "Send test delivery",
2881
+ "event": [],
2882
+ "request": {
2883
+ "method": "POST",
2884
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2885
+ "header": [],
2886
+ "url": {
2887
+ "raw": "{{baseUrl}}/auth/admin/webhooks/{{webhookId}}/test",
2888
+ "host": [
2889
+ "{{baseUrl}}"
2890
+ ],
2891
+ "path": [
2892
+ "auth",
2893
+ "admin",
2894
+ "webhooks",
2895
+ "{{webhookId}}",
2896
+ "test"
2897
+ ]
2898
+ }
2899
+ }
2900
+ },
2901
+ {
2902
+ "name": "Webhook deliveries",
2903
+ "event": [
2904
+ {
2905
+ "listen": "test",
2906
+ "script": {
2907
+ "type": "text/javascript",
2908
+ "exec": [
2909
+ "const body = pm.response.json();",
2910
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
2911
+ "if (read(body, \"deliveries.0.id\") !== undefined) { pm.collectionVariables.set(\"deliveryId\", read(body, \"deliveries.0.id\")); console.log(\"saved deliveryId\"); }"
2912
+ ]
2913
+ }
2914
+ }
2915
+ ],
2916
+ "request": {
2917
+ "method": "GET",
2918
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2919
+ "header": [],
2920
+ "url": {
2921
+ "raw": "{{baseUrl}}/auth/admin/webhooks/{{webhookId}}/deliveries",
2922
+ "host": [
2923
+ "{{baseUrl}}"
2924
+ ],
2925
+ "path": [
2926
+ "auth",
2927
+ "admin",
2928
+ "webhooks",
2929
+ "{{webhookId}}",
2930
+ "deliveries"
2931
+ ]
2932
+ }
2933
+ }
2934
+ },
2935
+ {
2936
+ "name": "Retry delivery",
2937
+ "event": [],
2938
+ "request": {
2939
+ "method": "POST",
2940
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2941
+ "header": [],
2942
+ "url": {
2943
+ "raw": "{{baseUrl}}/auth/admin/webhooks/{{webhookId}}/deliveries/{{deliveryId}}/retry",
2944
+ "host": [
2945
+ "{{baseUrl}}"
2946
+ ],
2947
+ "path": [
2948
+ "auth",
2949
+ "admin",
2950
+ "webhooks",
2951
+ "{{webhookId}}",
2952
+ "deliveries",
2953
+ "{{deliveryId}}",
2954
+ "retry"
2955
+ ]
2956
+ }
2957
+ }
2958
+ },
2959
+ {
2960
+ "name": "Rotate webhook secret",
2961
+ "event": [
2962
+ {
2963
+ "listen": "test",
2964
+ "script": {
2965
+ "type": "text/javascript",
2966
+ "exec": [
2967
+ "const body = pm.response.json();",
2968
+ "const read = (object, dottedPath) => dottedPath.split(\".\").reduce((value, key) => (value == null ? undefined : value[key]), object);",
2969
+ "if (read(body, \"signingSecret\") !== undefined) { pm.collectionVariables.set(\"webhookSecret\", read(body, \"signingSecret\")); console.log(\"saved webhookSecret\"); }"
2970
+ ]
2971
+ }
2972
+ }
2973
+ ],
2974
+ "request": {
2975
+ "method": "POST",
2976
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2977
+ "header": [],
2978
+ "url": {
2979
+ "raw": "{{baseUrl}}/auth/admin/webhooks/{{webhookId}}/rotate-secret",
2980
+ "host": [
2981
+ "{{baseUrl}}"
2982
+ ],
2983
+ "path": [
2984
+ "auth",
2985
+ "admin",
2986
+ "webhooks",
2987
+ "{{webhookId}}",
2988
+ "rotate-secret"
2989
+ ]
2990
+ }
2991
+ }
2992
+ },
2993
+ {
2994
+ "name": "Delete webhook",
2995
+ "event": [],
2996
+ "request": {
2997
+ "method": "DELETE",
2998
+ "description": "Requires an admin (a role listed in settings.admin.adminRoles).\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
2999
+ "header": [],
3000
+ "url": {
3001
+ "raw": "{{baseUrl}}/auth/admin/webhooks/{{webhookId}}",
3002
+ "host": [
3003
+ "{{baseUrl}}"
3004
+ ],
3005
+ "path": [
3006
+ "auth",
3007
+ "admin",
3008
+ "webhooks",
3009
+ "{{webhookId}}"
3010
+ ]
3011
+ }
3012
+ }
3013
+ }
3014
+ ]
3015
+ },
3016
+ {
3017
+ "name": "9. Public keys",
3018
+ "item": [
3019
+ {
3020
+ "name": "JWKS (public signing keys)",
3021
+ "event": [],
3022
+ "request": {
3023
+ "method": "GET",
3024
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
3025
+ "auth": {
3026
+ "type": "noauth"
3027
+ },
3028
+ "header": [],
3029
+ "url": {
3030
+ "raw": "{{baseUrl}}/.well-known/jwks.json",
3031
+ "host": [
3032
+ "{{baseUrl}}"
3033
+ ],
3034
+ "path": [
3035
+ ".well-known",
3036
+ "jwks.json"
3037
+ ]
3038
+ }
3039
+ }
3040
+ }
3041
+ ]
3042
+ },
3043
+ {
3044
+ "name": "10. Playground helpers",
3045
+ "item": [
3046
+ {
3047
+ "name": "Call an app route with the API key",
3048
+ "event": [],
3049
+ "request": {
3050
+ "method": "GET",
3051
+ "description": "Create the key first (Admin > Create API key, scope rides:read). After revoking it this returns 401 INVALID_API_KEY.\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
3052
+ "auth": {
3053
+ "type": "noauth"
3054
+ },
3055
+ "header": [
3056
+ {
3057
+ "key": "x-api-key",
3058
+ "value": "{{apiKey}}"
3059
+ }
3060
+ ],
3061
+ "url": {
3062
+ "raw": "{{baseUrl}}/sample/partner-export",
3063
+ "host": [
3064
+ "{{baseUrl}}"
3065
+ ],
3066
+ "path": [
3067
+ "sample",
3068
+ "partner-export"
3069
+ ]
3070
+ }
3071
+ }
3072
+ },
3073
+ {
3074
+ "name": "Same route with your user token",
3075
+ "event": [],
3076
+ "request": {
3077
+ "method": "GET",
3078
+ "description": "Signed-in users may call routes marked @ApiKeyScopes too.\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
3079
+ "header": [],
3080
+ "url": {
3081
+ "raw": "{{baseUrl}}/sample/partner-export",
3082
+ "host": [
3083
+ "{{baseUrl}}"
3084
+ ],
3085
+ "path": [
3086
+ "sample",
3087
+ "partner-export"
3088
+ ]
3089
+ }
3090
+ }
3091
+ },
3092
+ {
3093
+ "name": "Dev inbox (all emails and SMS)",
3094
+ "event": [],
3095
+ "request": {
3096
+ "method": "GET",
3097
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
3098
+ "auth": {
3099
+ "type": "noauth"
3100
+ },
3101
+ "header": [],
3102
+ "url": {
3103
+ "raw": "{{baseUrl}}/dev/api/inbox",
3104
+ "host": [
3105
+ "{{baseUrl}}"
3106
+ ],
3107
+ "path": [
3108
+ "dev",
3109
+ "api",
3110
+ "inbox"
3111
+ ]
3112
+ }
3113
+ }
3114
+ },
3115
+ {
3116
+ "name": "Auth events",
3117
+ "event": [],
3118
+ "request": {
3119
+ "method": "GET",
3120
+ "description": "Full request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
3121
+ "auth": {
3122
+ "type": "noauth"
3123
+ },
3124
+ "header": [],
3125
+ "url": {
3126
+ "raw": "{{baseUrl}}/dev/api/events",
3127
+ "host": [
3128
+ "{{baseUrl}}"
3129
+ ],
3130
+ "path": [
3131
+ "dev",
3132
+ "api",
3133
+ "events"
3134
+ ]
3135
+ }
3136
+ }
3137
+ },
3138
+ {
3139
+ "name": "Make me admin",
3140
+ "event": [],
3141
+ "request": {
3142
+ "method": "POST",
3143
+ "description": "Then run \"Refresh tokens\" so the new role is in the access token.\n\nFull request/response details: https://github.com/TechElusive/techelusive-authentication/tree/main/docs/endpoints",
3144
+ "auth": {
3145
+ "type": "noauth"
3146
+ },
3147
+ "header": [
3148
+ {
3149
+ "key": "Content-Type",
3150
+ "value": "application/json"
3151
+ }
3152
+ ],
3153
+ "url": {
3154
+ "raw": "{{baseUrl}}/dev/api/make-admin",
3155
+ "host": [
3156
+ "{{baseUrl}}"
3157
+ ],
3158
+ "path": [
3159
+ "dev",
3160
+ "api",
3161
+ "make-admin"
3162
+ ]
3163
+ },
3164
+ "body": {
3165
+ "mode": "raw",
3166
+ "raw": "{\n \"email\": \"{{email}}\"\n}",
3167
+ "options": {
3168
+ "raw": {
3169
+ "language": "json"
3170
+ }
3171
+ }
3172
+ }
3173
+ }
3174
+ }
3175
+ ]
3176
+ }
3177
+ ]
3178
+ }