@authup/server-core 1.0.0-beta.61 → 1.0.0-beta.63

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 (216) hide show
  1. package/dist/adapters/database/domains/client-scope/entity.d.ts.map +1 -1
  2. package/dist/adapters/database/domains/client-scope/entity.mjs +16 -8
  3. package/dist/adapters/database/domains/client-scope/entity.mjs.map +1 -1
  4. package/dist/adapters/database/domains/identity-provider-account/entity.d.ts.map +1 -1
  5. package/dist/adapters/database/domains/identity-provider-account/entity.mjs +1 -1
  6. package/dist/adapters/database/domains/identity-provider-account/entity.mjs.map +1 -1
  7. package/dist/adapters/database/domains/identity-provider-attribute/subscriber.d.ts +8 -1
  8. package/dist/adapters/database/domains/identity-provider-attribute/subscriber.d.ts.map +1 -1
  9. package/dist/adapters/database/domains/identity-provider-attribute/subscriber.mjs +14 -0
  10. package/dist/adapters/database/domains/identity-provider-attribute/subscriber.mjs.map +1 -1
  11. package/dist/adapters/database/migrations/mysql/1786631686318-SortIndexesAndAccountUniqueness.d.ts +50 -0
  12. package/dist/adapters/database/migrations/mysql/1786631686318-SortIndexesAndAccountUniqueness.d.ts.map +1 -0
  13. package/dist/adapters/database/migrations/mysql/1786631686318-SortIndexesAndAccountUniqueness.mjs +86 -0
  14. package/dist/adapters/database/migrations/mysql/1786631686318-SortIndexesAndAccountUniqueness.mjs.map +1 -0
  15. package/dist/adapters/database/migrations/postgres/1786631686318-SortIndexesAndAccountUniqueness.d.ts +42 -0
  16. package/dist/adapters/database/migrations/postgres/1786631686318-SortIndexesAndAccountUniqueness.d.ts.map +1 -0
  17. package/dist/adapters/database/migrations/postgres/1786631686318-SortIndexesAndAccountUniqueness.mjs +80 -0
  18. package/dist/adapters/database/migrations/postgres/1786631686318-SortIndexesAndAccountUniqueness.mjs.map +1 -0
  19. package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.d.ts.map +1 -1
  20. package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.mjs +8 -2
  21. package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.mjs.map +1 -1
  22. package/dist/adapters/http/adapters/oauth2/grant-types/utils/credentials.mjs +1 -1
  23. package/dist/adapters/http/adapters/oauth2/grant-types/utils/guess.mjs +1 -1
  24. package/dist/adapters/http/controllers/entities/client/module.mjs +2 -2
  25. package/dist/adapters/http/controllers/entities/identity-provider/module.d.ts +24 -4
  26. package/dist/adapters/http/controllers/entities/identity-provider/module.d.ts.map +1 -1
  27. package/dist/adapters/http/controllers/entities/identity-provider/module.mjs +117 -106
  28. package/dist/adapters/http/controllers/entities/identity-provider/module.mjs.map +1 -1
  29. package/dist/adapters/http/controllers/entities/identity-provider/types.d.ts +6 -4
  30. package/dist/adapters/http/controllers/entities/identity-provider/types.d.ts.map +1 -1
  31. package/dist/adapters/http/controllers/entities/realm/module.mjs +2 -2
  32. package/dist/adapters/http/controllers/entities/session/module.mjs +2 -2
  33. package/dist/adapters/http/controllers/entities/user/module.mjs +2 -2
  34. package/dist/adapters/http/controllers/entities/user-authenticator/module.mjs +2 -2
  35. package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.d.ts +2 -0
  36. package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.d.ts.map +1 -1
  37. package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.mjs +21 -3
  38. package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.mjs.map +1 -1
  39. package/dist/adapters/http/controllers/workflows/authorize/module.d.ts.map +1 -1
  40. package/dist/adapters/http/controllers/workflows/authorize/module.mjs +14 -5
  41. package/dist/adapters/http/controllers/workflows/authorize/module.mjs.map +1 -1
  42. package/dist/adapters/http/controllers/workflows/token/module.d.ts.map +1 -1
  43. package/dist/adapters/http/controllers/workflows/token/module.mjs +22 -9
  44. package/dist/adapters/http/controllers/workflows/token/module.mjs.map +1 -1
  45. package/dist/adapters/http/controllers/workflows/token/utils/extract.mjs +2 -1
  46. package/dist/adapters/http/controllers/workflows/token/utils/extract.mjs.map +1 -1
  47. package/dist/adapters/http/middleware/built-in/assets.mjs +1 -1
  48. package/dist/adapters/http/middleware/built-in/cors.d.ts.map +1 -1
  49. package/dist/adapters/http/middleware/built-in/cors.mjs.map +1 -1
  50. package/dist/adapters/http/middleware/built-in/error.d.ts.map +1 -1
  51. package/dist/adapters/http/middleware/built-in/error.mjs +10 -1
  52. package/dist/adapters/http/middleware/built-in/error.mjs.map +1 -1
  53. package/dist/adapters/http/request/helpers/param-id.d.ts.map +1 -1
  54. package/dist/adapters/http/request/helpers/param-id.mjs +2 -1
  55. package/dist/adapters/http/request/helpers/param-id.mjs.map +1 -1
  56. package/dist/adapters/http/ui/account-console/module.mjs +1 -1
  57. package/dist/adapters/http/ui/auth-console/http-client.mjs +1 -1
  58. package/dist/adapters/http/ui/auth-console/module.mjs +1 -1
  59. package/dist/adapters/http/ui/console-packages/module.d.ts +1 -1
  60. package/dist/adapters/http/ui/console-packages/module.mjs +2 -2
  61. package/dist/adapters/http/ui/console-packages/module.mjs.map +1 -1
  62. package/dist/adapters/http/ui/shared/html.d.ts.map +1 -1
  63. package/dist/adapters/http/ui/shared/html.mjs +1 -0
  64. package/dist/adapters/http/ui/shared/html.mjs.map +1 -1
  65. package/dist/app/modules/config/normalize.d.ts.map +1 -1
  66. package/dist/app/modules/config/normalize.mjs +2 -2
  67. package/dist/app/modules/config/normalize.mjs.map +1 -1
  68. package/dist/app/modules/config/read/env.mjs +1 -1
  69. package/dist/app/modules/config/types.d.ts +8 -0
  70. package/dist/app/modules/config/types.d.ts.map +1 -1
  71. package/dist/app/modules/database/repositories/event/repository.d.ts +2 -2
  72. package/dist/app/modules/database/repositories/event/repository.d.ts.map +1 -1
  73. package/dist/app/modules/database/repositories/event/repository.mjs +23 -6
  74. package/dist/app/modules/database/repositories/event/repository.mjs.map +1 -1
  75. package/dist/app/modules/database/repositories/identity-provider/repository.d.ts +3 -1
  76. package/dist/app/modules/database/repositories/identity-provider/repository.d.ts.map +1 -1
  77. package/dist/app/modules/database/repositories/identity-provider/repository.mjs +2 -2
  78. package/dist/app/modules/database/repositories/identity-provider/repository.mjs.map +1 -1
  79. package/dist/app/modules/database/repositories/identity-provider-account/repository.d.ts.map +1 -1
  80. package/dist/app/modules/database/repositories/identity-provider-account/repository.mjs +9 -1
  81. package/dist/app/modules/database/repositories/identity-provider-account/repository.mjs.map +1 -1
  82. package/dist/app/modules/http/modules/controller.d.ts.map +1 -1
  83. package/dist/app/modules/http/modules/controller.mjs +20 -6
  84. package/dist/app/modules/http/modules/controller.mjs.map +1 -1
  85. package/dist/app/modules/identity/module.d.ts.map +1 -1
  86. package/dist/app/modules/identity/module.mjs +6 -3
  87. package/dist/app/modules/identity/module.mjs.map +1 -1
  88. package/dist/app/modules/identity/repositories/user.d.ts +1 -0
  89. package/dist/app/modules/identity/repositories/user.d.ts.map +1 -1
  90. package/dist/app/modules/identity/repositories/user.mjs +3 -0
  91. package/dist/app/modules/identity/repositories/user.mjs.map +1 -1
  92. package/dist/app/modules/oauth2/constants.d.ts +2 -1
  93. package/dist/app/modules/oauth2/constants.d.ts.map +1 -1
  94. package/dist/app/modules/oauth2/constants.mjs +1 -0
  95. package/dist/app/modules/oauth2/constants.mjs.map +1 -1
  96. package/dist/app/modules/oauth2/module.d.ts.map +1 -1
  97. package/dist/app/modules/oauth2/module.mjs +5 -0
  98. package/dist/app/modules/oauth2/module.mjs.map +1 -1
  99. package/dist/app/modules/oauth2/repositories/authorize/state/repository.d.ts +1 -2
  100. package/dist/app/modules/oauth2/repositories/authorize/state/repository.d.ts.map +1 -1
  101. package/dist/app/modules/oauth2/repositories/authorize/state/repository.mjs +7 -16
  102. package/dist/app/modules/oauth2/repositories/authorize/state/repository.mjs.map +1 -1
  103. package/dist/app/modules/oauth2/repositories/constants.d.ts +1 -0
  104. package/dist/app/modules/oauth2/repositories/constants.d.ts.map +1 -1
  105. package/dist/app/modules/oauth2/repositories/constants.mjs +1 -0
  106. package/dist/app/modules/oauth2/repositories/constants.mjs.map +1 -1
  107. package/dist/app/modules/oauth2/repositories/federated-login/index.d.ts +2 -0
  108. package/dist/app/modules/oauth2/repositories/federated-login/index.d.ts.map +1 -0
  109. package/dist/app/modules/oauth2/repositories/federated-login/index.mjs +5 -0
  110. package/dist/app/modules/oauth2/repositories/federated-login/store.d.ts +9 -0
  111. package/dist/app/modules/oauth2/repositories/federated-login/store.d.ts.map +1 -0
  112. package/dist/app/modules/oauth2/repositories/federated-login/store.mjs +33 -0
  113. package/dist/app/modules/oauth2/repositories/federated-login/store.mjs.map +1 -0
  114. package/dist/app/modules/oauth2/repositories/index.d.ts +1 -0
  115. package/dist/app/modules/oauth2/repositories/index.d.ts.map +1 -1
  116. package/dist/app/modules/oauth2/repositories/index.mjs +3 -1
  117. package/dist/app/modules/runtime/module.mjs +2 -2
  118. package/dist/cli/commands/migration.mjs +1 -1
  119. package/dist/core/entities/client-scope/schema.d.ts.map +1 -1
  120. package/dist/core/entities/client-scope/schema.mjs +16 -1
  121. package/dist/core/entities/client-scope/schema.mjs.map +1 -1
  122. package/dist/core/entities/event/constants.d.ts +9 -0
  123. package/dist/core/entities/event/constants.d.ts.map +1 -1
  124. package/dist/core/entities/event/constants.mjs +9 -1
  125. package/dist/core/entities/event/constants.mjs.map +1 -1
  126. package/dist/core/entities/event/entity-event-handler.d.ts.map +1 -1
  127. package/dist/core/entities/event/entity-event-handler.mjs +14 -1
  128. package/dist/core/entities/event/entity-event-handler.mjs.map +1 -1
  129. package/dist/core/entities/event/index.mjs +2 -2
  130. package/dist/core/entities/event/types.d.ts +11 -2
  131. package/dist/core/entities/event/types.d.ts.map +1 -1
  132. package/dist/core/entities/identity-provider/types.d.ts +9 -1
  133. package/dist/core/entities/identity-provider/types.d.ts.map +1 -1
  134. package/dist/core/entities/identity-provider-account/types.d.ts +6 -0
  135. package/dist/core/entities/identity-provider-account/types.d.ts.map +1 -1
  136. package/dist/core/entities/identity-provider-account/types.mjs.map +1 -1
  137. package/dist/core/entities/index.mjs +2 -2
  138. package/dist/core/identity/entities/user/types.d.ts +1 -0
  139. package/dist/core/identity/entities/user/types.d.ts.map +1 -1
  140. package/dist/core/identity/index.mjs +12 -11
  141. package/dist/core/identity/provider/account/module.d.ts +3 -0
  142. package/dist/core/identity/provider/account/module.d.ts.map +1 -1
  143. package/dist/core/identity/provider/account/module.mjs +54 -27
  144. package/dist/core/identity/provider/account/module.mjs.map +1 -1
  145. package/dist/core/identity/provider/account/types.d.ts +7 -0
  146. package/dist/core/identity/provider/account/types.d.ts.map +1 -1
  147. package/dist/core/identity/provider/authentication/index.mjs +3 -2
  148. package/dist/core/identity/provider/authentication/protocols/index.mjs +2 -1
  149. package/dist/core/identity/provider/authentication/protocols/oauth2/assurance.d.ts +46 -0
  150. package/dist/core/identity/provider/authentication/protocols/oauth2/assurance.d.ts.map +1 -0
  151. package/dist/core/identity/provider/authentication/protocols/oauth2/assurance.mjs +89 -0
  152. package/dist/core/identity/provider/authentication/protocols/oauth2/assurance.mjs.map +1 -0
  153. package/dist/core/identity/provider/authentication/protocols/oauth2/index.d.ts +1 -0
  154. package/dist/core/identity/provider/authentication/protocols/oauth2/index.d.ts.map +1 -1
  155. package/dist/core/identity/provider/authentication/protocols/oauth2/index.mjs +2 -1
  156. package/dist/core/identity/provider/authentication/protocols/oauth2/module.d.ts.map +1 -1
  157. package/dist/core/identity/provider/authentication/protocols/oauth2/module.mjs +9 -2
  158. package/dist/core/identity/provider/authentication/protocols/oauth2/module.mjs.map +1 -1
  159. package/dist/core/identity/provider/index.mjs +12 -11
  160. package/dist/core/index.mjs +16 -12
  161. package/dist/core/oauth2/authorization/code-request/verifier/module.d.ts.map +1 -1
  162. package/dist/core/oauth2/authorization/code-request/verifier/module.mjs +7 -1
  163. package/dist/core/oauth2/authorization/code-request/verifier/module.mjs.map +1 -1
  164. package/dist/core/oauth2/authorization/helpers.d.ts.map +1 -1
  165. package/dist/core/oauth2/authorization/helpers.mjs +6 -1
  166. package/dist/core/oauth2/authorization/helpers.mjs.map +1 -1
  167. package/dist/core/oauth2/authorization/module.d.ts.map +1 -1
  168. package/dist/core/oauth2/authorization/module.mjs +5 -3
  169. package/dist/core/oauth2/authorization/module.mjs.map +1 -1
  170. package/dist/core/oauth2/authorization/state/module.mjs +1 -2
  171. package/dist/core/oauth2/authorization/state/module.mjs.map +1 -1
  172. package/dist/core/oauth2/authorization/state/types.d.ts +13 -2
  173. package/dist/core/oauth2/authorization/state/types.d.ts.map +1 -1
  174. package/dist/core/oauth2/end-session/service.d.ts.map +1 -1
  175. package/dist/core/oauth2/end-session/service.mjs +1 -0
  176. package/dist/core/oauth2/end-session/service.mjs.map +1 -1
  177. package/dist/core/oauth2/federated-login/constants.d.ts +22 -0
  178. package/dist/core/oauth2/federated-login/constants.d.ts.map +1 -0
  179. package/dist/core/oauth2/federated-login/constants.mjs +27 -0
  180. package/dist/core/oauth2/federated-login/constants.mjs.map +1 -0
  181. package/dist/core/oauth2/federated-login/index.d.ts +4 -0
  182. package/dist/core/oauth2/federated-login/index.d.ts.map +1 -0
  183. package/dist/core/oauth2/federated-login/index.mjs +7 -0
  184. package/dist/core/oauth2/federated-login/module.d.ts +29 -0
  185. package/dist/core/oauth2/federated-login/module.d.ts.map +1 -0
  186. package/dist/core/oauth2/federated-login/module.mjs +193 -0
  187. package/dist/core/oauth2/federated-login/module.mjs.map +1 -0
  188. package/dist/core/oauth2/federated-login/types.d.ts +196 -0
  189. package/dist/core/oauth2/federated-login/types.d.ts.map +1 -0
  190. package/dist/core/oauth2/federated-login/types.mjs +36 -0
  191. package/dist/core/oauth2/federated-login/types.mjs.map +1 -0
  192. package/dist/core/oauth2/grant-types/authorize.mjs +1 -1
  193. package/dist/core/oauth2/grant-types/client-credentials.mjs +1 -1
  194. package/dist/core/oauth2/grant-types/identity.mjs +1 -1
  195. package/dist/core/oauth2/grant-types/password.mjs +1 -1
  196. package/dist/core/oauth2/grant-types/refresh-token.mjs +1 -1
  197. package/dist/core/oauth2/index.d.ts +1 -0
  198. package/dist/core/oauth2/index.d.ts.map +1 -1
  199. package/dist/core/oauth2/index.mjs +5 -1
  200. package/dist/core/oauth2/token/verifier/module.d.ts.map +1 -1
  201. package/dist/core/oauth2/token/verifier/module.mjs +3 -3
  202. package/dist/core/oauth2/token/verifier/module.mjs.map +1 -1
  203. package/dist/core/provisioning/entities/policy/validator.d.ts.map +1 -1
  204. package/dist/core/provisioning/entities/policy/validator.mjs +2 -1
  205. package/dist/core/provisioning/entities/policy/validator.mjs.map +1 -1
  206. package/dist/core/provisioning/entities/realm/wildcard-validator.d.ts.map +1 -1
  207. package/dist/core/provisioning/entities/realm/wildcard-validator.mjs +2 -1
  208. package/dist/core/provisioning/entities/realm/wildcard-validator.mjs.map +1 -1
  209. package/dist/core/security/policy/evaluator.mjs.map +1 -1
  210. package/dist/node_modules/@ebec/core/dist/index.mjs +130 -0
  211. package/dist/node_modules/@ebec/core/dist/index.mjs.map +1 -0
  212. package/dist/swagger.json +119 -43
  213. package/dist/utils/error.d.ts.map +1 -1
  214. package/dist/utils/error.mjs +5 -6
  215. package/dist/utils/error.mjs.map +1 -1
  216. package/package.json +29 -29
@@ -1,21 +1,20 @@
1
1
  import type { IAppEvent } from 'routup';
2
2
  import type { IdentityProvider, IdentityProviderAccount } from '@authup/core-kit';
3
3
  import type { Logger } from '@authup/server-kit';
4
+ import type { OAuth2TokenGrantResponse } from '@authup/specs';
4
5
  import type { EntityCollectionResponse, EntityRecordResponse, IdentityProviderCreatePayload, IdentityProviderLinkConfirmPayload, IdentityProviderLinkRequestResponse, IdentityProviderSavePayload, IdentityProviderUpdatePayload } from '@authup/core-http-kit';
5
- import type { IEventService, IIdentityProviderAccountLinkStore, IIdentityProviderAccountManager, IIdentityProviderRepository, IOAuth2AccessPolicyEvaluator, IOAuth2AuthorizationCodeIssuer, IOAuth2AuthorizationCodeRequestVerifier, IOAuth2AuthorizationStateManager, IRealmRepository } from '../../../../../core/index.ts';
6
+ import type { IEventService, IIdentityProviderAccountLinkStore, IIdentityProviderAccountManager, IIdentityProviderRepository, IOAuth2AuthorizationCodeRequestVerifier, IOAuth2AuthorizationStateManager, IOAuth2FederatedLoginService } from '../../../../../core/index.ts';
6
7
  import { OAuth2AuthorizationCodeRequestValidator } from '../../../../../core/index.ts';
7
8
  import type { IdentityProviderControllerContext, IdentityProviderControllerOptions } from './types.ts';
8
9
  export declare class IdentityProviderController {
9
10
  protected options: IdentityProviderControllerOptions;
10
11
  protected repository: IIdentityProviderRepository;
11
- protected realmRepository: IRealmRepository;
12
12
  protected accountManager: IIdentityProviderAccountManager;
13
13
  protected linkStore: IIdentityProviderAccountLinkStore;
14
14
  protected codeRequestVerifier: IOAuth2AuthorizationCodeRequestVerifier;
15
15
  protected codeRequestValidator: OAuth2AuthorizationCodeRequestValidator;
16
16
  protected stateManager: IOAuth2AuthorizationStateManager;
17
- protected codeIssuer: IOAuth2AuthorizationCodeIssuer;
18
- protected accessPolicyEvaluator?: IOAuth2AccessPolicyEvaluator;
17
+ protected loginService: IOAuth2FederatedLoginService;
19
18
  protected eventService?: IEventService;
20
19
  protected logger?: Logger;
21
20
  constructor(ctx: IdentityProviderControllerContext);
@@ -28,6 +27,7 @@ export declare class IdentityProviderController {
28
27
  authorizeOut(_id: string, event: IAppEvent): Promise<Response>;
29
28
  linkRequest(_id: string, event: IAppEvent): Promise<IdentityProviderLinkRequestResponse>;
30
29
  authorizeIn(_id: string, event: IAppEvent): Promise<Response>;
30
+ completeLogin(_id: string, event: IAppEvent): Promise<OAuth2TokenGrantResponse>;
31
31
  private write;
32
32
  /**
33
33
  * Callback half of the account-linking round-trip (plan 091): the
@@ -45,6 +45,26 @@ export declare class IdentityProviderController {
45
45
  private buildHostedAuthorizeURL;
46
46
  private resolve;
47
47
  private buildProviderAuthenticator;
48
+ /**
49
+ * Scoped to the routes that read it, so the cookie never rides an
50
+ * ordinary API request, and to publicUrl's base path, since a sub-path
51
+ * deployment mounts every route under it.
52
+ */
53
+ private buildFederatedLoginCookiePath;
54
+ private setFederatedLoginCookie;
55
+ /**
56
+ * The completion answers with a token pair and authenticates on a cookie
57
+ * alone, so it must be reachable only from the hosted page's own origin.
58
+ *
59
+ * CORS cannot carry that here: the default reflects every origin WITH
60
+ * credentials, and `SameSite` is scoped to the registrable domain rather
61
+ * than the origin, so a sibling subdomain's script is same-site and would
62
+ * both send the cookie and be allowed to read the response. A browser
63
+ * sends `Origin` on every POST, so requiring it to be publicUrl's own is
64
+ * what closes that. A request without the header is not a browser and
65
+ * carries no cookie of ours to begin with.
66
+ */
67
+ private assertSameOrigin;
48
68
  private saveAuthorizationState;
49
69
  private verifyAuthorizationState;
50
70
  }
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/controllers/entities/identity-provider/module.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/controllers/entities/identity-provider/module.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,10 @@ import { RECORD_QUERY_PARAMETERS, describeQuerySchema } from "../../../../../cor
5
5
  import { identityProviderSchema } from "../../../../../core/entities/identity-provider/schema.mjs";
6
6
  import { decodeQuery } from "../../../../../core/query/module.mjs";
7
7
  import { OAuth2AuthorizationCodeRequestValidator } from "../../../../../core/oauth2/authorization/code-request/validator.mjs";
8
- import { toIdentityPolicyData } from "../../../../../core/identity/permission/identity-policy-data.mjs";
8
+ import { OAUTH2_FEDERATED_LOGIN_COOKIE, OAUTH2_FEDERATED_LOGIN_TTL } from "../../../../../core/oauth2/federated-login/constants.mjs";
9
+ import { describeError } from "../../../../../utils/error.mjs";
10
+ import { resolveURL } from "../../../../../utils/url.mjs";
11
+ import "../../../../../utils/index.mjs";
9
12
  import { createIdentityProviderOAuth2Authenticator } from "../../../../../core/identity/provider/authentication/factory.mjs";
10
13
  import "../../../../../core/index.mjs";
11
14
  import { useRequestPermissionEvaluator } from "../../../request/permission/helper.mjs";
@@ -17,19 +20,18 @@ import { applyRouteRealmIDToBody, getRequestRealmID } from "../../../request/hel
17
20
  import { useRequestEventContext } from "../../../request/event-context.mjs";
18
21
  import "../../../request/index.mjs";
19
22
  import { ForceLoggedInMiddleware } from "../../../middleware/built-in/loggedin/module.mjs";
20
- import { describeError } from "../../../../../utils/error.mjs";
21
- import { resolveURL } from "../../../../../utils/url.mjs";
22
- import "../../../../../utils/index.mjs";
23
23
  import "../../../middleware/index.mjs";
24
- import { ValidatorGroup, base64URLDecode, isObject, isUUID } from "@authup/kit";
25
- import { EventName, EventRefType, EventScope, IdentityProviderAttributesValidator, IdentityProviderValidator, IdentityType, PermissionName, SessionAuthMethod, isOAuth2IdentityProvider, isOpenIDIdentityProvider } from "@authup/core-kit";
24
+ import { ValidatorGroup, base64URLDecode, createNanoID, getURLBasePath, isObject, isUUID } from "@authup/kit";
25
+ import { EventName, EventRefType, EventScope, IdentityProviderAttributesValidator, IdentityProviderValidator, IdentityType, PermissionName, isOAuth2IdentityProvider, isOpenIDIdentityProvider } from "@authup/core-kit";
26
26
  import { BuiltInPolicyType, definePolicyData } from "@authup/access";
27
- import { BadRequestError, EntityInactiveError, EntityNotFoundError } from "@authup/errors";
28
- import { OAuth2ErrorCode, OAuth2RequestError } from "@authup/specs";
27
+ import { BadRequestError, EntityNotFoundError } from "@authup/errors";
28
+ import { OAuth2RequestError } from "@authup/specs";
29
29
  import { URL } from "node:url";
30
30
  import { getRequestHeader, getRequestIP, sendRedirect } from "routup";
31
+ import { setResponseCookie, unsetResponseCookie, useRequestCookie } from "@routup/basic/cookie";
31
32
  import { readRequestBody } from "@routup/basic/body";
32
33
  import { useRequestQuery } from "@routup/basic/query";
34
+ import { IDENTITY_PROVIDER_LOGIN_NOT_PENDING } from "@authup/core-http-kit";
33
35
  import { DBody, DContext, DController, DDelete, DGet, DPath, DPost, DPut, DTags } from "@routup/decorators";
34
36
  //#region src/adapters/http/controllers/entities/identity-provider/module.ts
35
37
  function _ts_decorate(decorators, target, key, desc) {
@@ -49,27 +51,23 @@ function _ts_param(paramIndex, decorator) {
49
51
  var IdentityProviderController = class {
50
52
  options;
51
53
  repository;
52
- realmRepository;
53
54
  accountManager;
54
55
  linkStore;
55
56
  codeRequestVerifier;
56
57
  codeRequestValidator;
57
58
  stateManager;
58
- codeIssuer;
59
- accessPolicyEvaluator;
59
+ loginService;
60
60
  eventService;
61
61
  logger;
62
62
  constructor(ctx) {
63
63
  this.options = ctx.options;
64
64
  this.repository = ctx.repository;
65
- this.realmRepository = ctx.realmRepository;
66
65
  this.accountManager = ctx.accountManager;
67
66
  this.linkStore = ctx.linkStore;
68
- this.codeIssuer = ctx.codeIssuer;
69
67
  this.codeRequestVerifier = ctx.codeRequestVerifier;
70
68
  this.codeRequestValidator = new OAuth2AuthorizationCodeRequestValidator();
71
69
  this.stateManager = ctx.stateManager;
72
- this.accessPolicyEvaluator = ctx.accessPolicyEvaluator;
70
+ this.loginService = ctx.loginService;
73
71
  this.eventService = ctx.eventService;
74
72
  this.logger = ctx.logger;
75
73
  }
@@ -78,19 +76,6 @@ var IdentityProviderController = class {
78
76
  schema: identityProviderSchema,
79
77
  actor: buildActorContext(event)
80
78
  }));
81
- try {
82
- const permissionEvaluator = useRequestPermissionEvaluator(event);
83
- await permissionEvaluator.preEvaluate({ name: PermissionName.IDENTITY_PROVIDER_READ });
84
- for (const datum of data) try {
85
- await permissionEvaluator.evaluate({
86
- name: PermissionName.IDENTITY_PROVIDER_READ,
87
- data: definePolicyData({
88
- [BuiltInPolicyType.ATTRIBUTES]: datum,
89
- [BuiltInPolicyType.REALM_MATCH]: datum.realmId ?? null
90
- })
91
- });
92
- } catch {}
93
- } catch {}
94
79
  return {
95
80
  data,
96
81
  meta: {
@@ -103,15 +88,17 @@ var IdentityProviderController = class {
103
88
  const paramId = useRequestParamID(event, { isUUID: false });
104
89
  const entity = await this.repository.findOneByIdOrName(paramId, getRequestRealmID(event));
105
90
  if (!entity) throw new EntityNotFoundError();
106
- try {
107
- await useRequestPermissionEvaluator(event).evaluate({
108
- name: PermissionName.IDENTITY_PROVIDER_READ,
109
- data: definePolicyData({
110
- [BuiltInPolicyType.ATTRIBUTES]: entity,
111
- [BuiltInPolicyType.REALM_MATCH]: entity.realmId ?? null
112
- })
113
- });
114
- } catch {}
91
+ await useRequestPermissionEvaluator(event).evaluateOneOf({
92
+ name: [
93
+ PermissionName.IDENTITY_PROVIDER_READ,
94
+ PermissionName.IDENTITY_PROVIDER_UPDATE,
95
+ PermissionName.IDENTITY_PROVIDER_DELETE
96
+ ],
97
+ data: definePolicyData({
98
+ [BuiltInPolicyType.ATTRIBUTES]: entity,
99
+ [BuiltInPolicyType.REALM_MATCH]: entity.realmId ?? null
100
+ })
101
+ });
115
102
  return {
116
103
  data: entity,
117
104
  meta: { schema: describeQuerySchema(identityProviderSchema, RECORD_QUERY_PARAMETERS) }
@@ -152,22 +139,25 @@ var IdentityProviderController = class {
152
139
  const id = useRequestParamID(event);
153
140
  const entity = await this.resolve(id);
154
141
  if (!isOAuth2IdentityProvider(entity) && !isOpenIDIdentityProvider(entity)) throw new BadRequestError("Only an identity-provider based on the oauth protocol supports authorize redirect.");
155
- const authenticator = this.buildProviderAuthenticator(entity);
156
- let codeRequest;
142
+ if (!entity.enabled) throw new BadRequestError("The identity provider is not enabled.");
157
143
  const query = useRequestQuery(event);
158
- if (typeof query.codeRequest === "string") {
159
- let codeRequestDecoded;
160
- try {
161
- codeRequestDecoded = JSON.parse(base64URLDecode(query.codeRequest));
162
- } catch {
163
- throw OAuth2RequestError.malformed("The code request is malformed and can not be parsed.");
164
- }
165
- const codeRequestValidated = await this.codeRequestValidator.run(codeRequestDecoded);
166
- const data = await this.codeRequestVerifier.verify(codeRequestValidated);
167
- if (data.client.realmId && entity.realmId && entity.realmId !== data.client.realmId) throw OAuth2RequestError.malformed("The provider and client realm do not match.");
168
- codeRequest = data.data;
144
+ if (typeof query.codeRequest !== "string") throw OAuth2RequestError.malformed("A federated login requires an authorization code request.");
145
+ let codeRequestDecoded;
146
+ try {
147
+ codeRequestDecoded = JSON.parse(base64URLDecode(query.codeRequest));
148
+ } catch {
149
+ throw OAuth2RequestError.malformed("The code request is malformed and can not be parsed.");
169
150
  }
170
- const state = await this.saveAuthorizationState(event, { codeRequest });
151
+ const codeRequestValidated = await this.codeRequestValidator.run(codeRequestDecoded);
152
+ const data = await this.codeRequestVerifier.verify(codeRequestValidated);
153
+ if (data.client.realmId && entity.realmId && entity.realmId !== data.client.realmId) throw OAuth2RequestError.malformed("The provider and client realm do not match.");
154
+ const authenticator = this.buildProviderAuthenticator(entity);
155
+ const browserNonce = createNanoID();
156
+ this.setFederatedLoginCookie(event, browserNonce);
157
+ const state = await this.saveAuthorizationState(event, {
158
+ codeRequest: data.data,
159
+ browserNonce
160
+ });
171
161
  return sendRedirect(event, authenticator.buildRedirectURL({ state }));
172
162
  }
173
163
  async linkRequest(_id, event) {
@@ -192,67 +182,47 @@ var IdentityProviderController = class {
192
182
  const data = await this.verifyAuthorizationState(event);
193
183
  const { link } = data;
194
184
  if (link) return this.completeLink(event, entity, data, link);
195
- if (entity.realmId && data.codeRequest && data.codeRequest.realm_id && data.codeRequest.realm_id !== entity.realmId) throw OAuth2RequestError.malformed("The provider and client realm do not match.");
196
- const { code } = useRequestQuery(event);
197
- if (typeof code !== "string" || code.length === 0) throw new BadRequestError("The authorization code is missing.");
198
- const verified = data.codeRequest ? await this.codeRequestVerifier.verify(data.codeRequest) : void 0;
199
- if (!entity.enabled) throw new BadRequestError("The identity provider is not enabled.");
200
- const user = await this.buildProviderAuthenticator(entity, { clientId: verified?.data.client_id }).authenticate({ code });
201
- if (!user.active) throw new EntityInactiveError({ entity: "user" });
202
- const realm = await this.realmRepository.resolve(entity.realmId, true);
203
- if (verified?.client.accessPolicyId) {
204
- let allowed = false;
205
- const subject = toIdentityPolicyData({
206
- type: IdentityType.USER,
207
- data: {
208
- ...user,
209
- realm
210
- }
211
- });
212
- if (this.accessPolicyEvaluator && subject) allowed = await this.accessPolicyEvaluator.evaluate(verified.client.accessPolicyId, subject);
213
- if (!allowed) {
214
- const url = this.buildHostedAuthorizeURL(verified.data);
215
- url.searchParams.set("error", OAuth2ErrorCode.ACCESS_DENIED);
216
- return sendRedirect(event, url.href);
217
- }
185
+ if (!data.codeRequest) throw OAuth2RequestError.malformed("The state carries no authorization code request.");
186
+ const browserNonce = useRequestCookie(event, OAUTH2_FEDERATED_LOGIN_COOKIE);
187
+ if (!data.browserNonce || typeof browserNonce !== "string" || browserNonce !== data.browserNonce) return sendRedirect(event, this.buildHostedAuthorizeURL(data.codeRequest).href);
188
+ const { code, error } = useRequestQuery(event);
189
+ if (typeof error === "string" && error.length > 0) {
190
+ this.logger?.info(`The identity provider ${entity.id} answered the authorization with ${JSON.stringify(error.slice(0, 64))}.`);
191
+ return sendRedirect(event, this.buildHostedAuthorizeURL(data.codeRequest).href);
218
192
  }
219
- const authorizationCode = await this.codeIssuer.issue(verified?.data ?? { response_type: "code" }, {
220
- type: IdentityType.USER,
221
- data: {
222
- ...user,
223
- realm
224
- }
225
- }, { authMethod: SessionAuthMethod.EXTERNAL });
226
- await this.eventService?.record({
227
- scope: EventScope.OAUTH2,
228
- name: EventName.AUTHORIZE,
229
- refType: EventRefType.CLIENT,
230
- refId: verified?.data.client_id ?? null,
231
- clientId: verified?.data.client_id ?? null,
232
- sessionId: null,
233
- actorType: IdentityType.USER,
234
- actorId: user.id,
235
- actorName: user.name,
236
- realmId: verified?.data.realm_id ?? realm.id,
237
- requestIpAddress: getRequestIP(event) ?? null,
238
- requestUserAgent: getRequestHeader(event, "user-agent") ?? null,
239
- data: {
240
- reason: "federated",
241
- providerId: entity.id,
242
- providerName: entity.name,
243
- ...verified?.data.scope ? { scope: verified.data.scope } : {}
193
+ if (typeof code !== "string" || code.length === 0) throw new BadRequestError("The authorization code is missing.");
194
+ const result = await this.loginService.complete({
195
+ provider: entity,
196
+ codeRequest: data.codeRequest,
197
+ code,
198
+ request: {
199
+ ipAddress: getRequestIP(event),
200
+ userAgent: getRequestHeader(event, "user-agent")
244
201
  }
245
202
  });
246
- if (verified?.redirectUriVerified && verified.data.redirect_uri) {
247
- const url = new URL(verified.data.redirect_uri);
248
- url.searchParams.set("code", authorizationCode.id);
249
- if (verified.data.state) url.searchParams.set("state", verified.data.state);
203
+ const url = this.buildHostedAuthorizeURL(result.codeRequest);
204
+ if (result.kind === "refused") {
205
+ if (result.error) url.searchParams.set("error", result.error);
250
206
  return sendRedirect(event, url.href);
251
207
  }
252
- const url = new URL(this.options.baseURL);
253
- url.searchParams.set("code", authorizationCode.id);
208
+ this.setFederatedLoginCookie(event, result.pendingLoginId);
209
+ url.searchParams.set("provider", entity.id);
254
210
  return sendRedirect(event, url.href);
255
211
  }
212
+ async completeLogin(_id, event) {
213
+ const id = useRequestParamID(event);
214
+ this.assertSameOrigin(event);
215
+ const pendingLoginId = useRequestCookie(event, OAUTH2_FEDERATED_LOGIN_COOKIE);
216
+ if (typeof pendingLoginId !== "string" || pendingLoginId.length === 0) throw new BadRequestError({
217
+ message: "The login request is unknown or expired.",
218
+ data: { reason: IDENTITY_PROVIDER_LOGIN_NOT_PENDING }
219
+ });
220
+ unsetResponseCookie(event, OAUTH2_FEDERATED_LOGIN_COOKIE, { path: this.buildFederatedLoginCookiePath() });
221
+ return this.loginService.completeHandoff({
222
+ pendingLoginId,
223
+ providerId: id
224
+ });
225
+ }
256
226
  async write(event, options = {}) {
257
227
  let group;
258
228
  const id = getRequestParamID(event, { isUUID: false });
@@ -301,8 +271,9 @@ var IdentityProviderController = class {
301
271
  }
302
272
  await this.repository.checkUniqueness(data, entity || void 0);
303
273
  if (entity) {
274
+ const keepAll = entity.protocol === data.protocol;
304
275
  entity = this.repository.merge(entity, data);
305
- await this.repository.saveWithEA(entity, attributes);
276
+ await this.repository.saveWithEA(entity, attributes, { keepAll });
306
277
  event.response.status = 202;
307
278
  return {
308
279
  data: entity,
@@ -426,6 +397,38 @@ var IdentityProviderController = class {
426
397
  }
427
398
  });
428
399
  }
400
+ /**
401
+ * Scoped to the routes that read it, so the cookie never rides an
402
+ * ordinary API request, and to publicUrl's base path, since a sub-path
403
+ * deployment mounts every route under it.
404
+ */ buildFederatedLoginCookiePath() {
405
+ return `${getURLBasePath(this.options.baseURL)}/identity-providers`;
406
+ }
407
+ setFederatedLoginCookie(event, value) {
408
+ setResponseCookie(event, OAUTH2_FEDERATED_LOGIN_COOKIE, value, {
409
+ httpOnly: true,
410
+ sameSite: "lax",
411
+ secure: new URL(this.options.baseURL).protocol === "https:",
412
+ path: this.buildFederatedLoginCookiePath(),
413
+ maxAge: OAUTH2_FEDERATED_LOGIN_TTL / 1e3
414
+ });
415
+ }
416
+ /**
417
+ * The completion answers with a token pair and authenticates on a cookie
418
+ * alone, so it must be reachable only from the hosted page's own origin.
419
+ *
420
+ * CORS cannot carry that here: the default reflects every origin WITH
421
+ * credentials, and `SameSite` is scoped to the registrable domain rather
422
+ * than the origin, so a sibling subdomain's script is same-site and would
423
+ * both send the cookie and be allowed to read the response. A browser
424
+ * sends `Origin` on every POST, so requiring it to be publicUrl's own is
425
+ * what closes that. A request without the header is not a browser and
426
+ * carries no cookie of ours to begin with.
427
+ */ assertSameOrigin(event) {
428
+ const origin = getRequestHeader(event, "origin");
429
+ if (typeof origin !== "string" || origin.length === 0) return;
430
+ if (origin !== new URL(this.options.baseURL).origin) throw new BadRequestError("The login request is unknown or expired.");
431
+ }
429
432
  async saveAuthorizationState(event, data = {}) {
430
433
  return this.stateManager.save({
431
434
  ...data,
@@ -450,7 +453,7 @@ _ts_decorate([
450
453
  _ts_metadata("design:returntype", Promise)
451
454
  ], IdentityProviderController.prototype, "getProviders", null);
452
455
  _ts_decorate([
453
- DGet("/:id", []),
456
+ DGet("/:id", [ForceLoggedInMiddleware]),
454
457
  _ts_param(0, DPath("id")),
455
458
  _ts_param(1, DContext()),
456
459
  _ts_metadata("design:type", Function),
@@ -523,6 +526,14 @@ _ts_decorate([
523
526
  _ts_metadata("design:paramtypes", [String, typeof IAppEvent === "undefined" ? Object : IAppEvent]),
524
527
  _ts_metadata("design:returntype", Promise)
525
528
  ], IdentityProviderController.prototype, "authorizeIn", null);
529
+ _ts_decorate([
530
+ DPost("/:id/login-complete", []),
531
+ _ts_param(0, DPath("id")),
532
+ _ts_param(1, DContext()),
533
+ _ts_metadata("design:type", Function),
534
+ _ts_metadata("design:paramtypes", [String, typeof IAppEvent === "undefined" ? Object : IAppEvent]),
535
+ _ts_metadata("design:returntype", Promise)
536
+ ], IdentityProviderController.prototype, "completeLogin", null);
526
537
  _ts_decorate([
527
538
  DPost("/:id/link-confirm", [ForceLoggedInMiddleware]),
528
539
  _ts_param(0, DPath("id")),