53 Commits

Author SHA1 Message Date
e118ed76de fix: unwarranted passcode data in webhooks (#2279) 2025-10-24 12:30:03 +02:00
d9f9050b5e fix: consistently use persisters with connection (#2276) 2025-10-16 13:01:40 +02:00
7fe0862369 PKCE OAuth flow (#2266)
* feat: add auth prompt config option

* feat: add pkce oauth flow

When the oauth flow is initialized with a `code_verifier` the state cookie is optional and on hanko_token exchange the client must also send the `code_verifier` in addition to the `hanko_token`.

* fix: fix runtime errors & tests
2025-10-13 14:28:42 +02:00
ade86cc318 feat: add auth prompt config option (#2260) 2025-10-13 14:22:22 +02:00
a7d434fdc1 fix: check for SAML before email existence (#2270)
Check if the domain is registered for a SAML provider before checking if the email already exists.
2025-10-13 14:16:22 +02:00
7a78b8e172 fix: change module name corresponding to version 2025-09-25 19:15:20 +02:00
d026db6263 fix: take privacy setting into account when adding an email (#2208)
When adding an email take the show_account_existence_hints setting into account when for returning an error or continue to passcode input.
2025-08-26 16:16:43 +02:00
f231ae7e4a fix: oauth third party authentication with case insensitive email (#2196)
* feat: replace std slices

* feat: go mod tidy

* fix #2193: lowercase email

---------

Co-authored-by: franklin <kevin@franklinkim.de>
2025-07-24 14:08:40 +02:00
b9bcf5e69b feat: user metadata 2025-05-16 13:47:10 +02:00
1d22a8f7a8 fix: add missing validation to the pw recovery action (#2151) 2025-05-08 10:59:28 +02:00
404e52f919 fix: no input error on invalid passkey (#2141) 2025-04-29 16:38:04 +02:00
6af695345b Feat: js flow api sdk (#2097) 2025-04-24 22:52:28 +02:00
efeca4a76f feat: custom jwt claims 2025-04-16 15:17:48 +02:00
122b738105 Fix login method chooser (#2111)
* fix: remove password option from method chooser

When Privacy.OnlyShowActualLoginMethods config setting is enabled and the user has no password or passwords are disabled the password option must not be available in the login method chooser.

* fix: remove passcode option from method chooser

When Privacy.OnlyShowActualLoginMethods config setting is enabled and the user has either no email address or emails are disabled or emails can not be used for authentication, the passcode option must not be available in the login method chooser.
2025-04-04 10:17:44 +02:00
829a2849a6 feat: add passkey option to login method chooser (#2100) 2025-03-28 10:46:01 +01:00
26063d3b62 feat: add privacy settings (#2072)
Add two privacy settings, one that disables account enumeration and one that only returns actual configured login methods of the user.
2025-03-11 09:49:08 +01:00
7e1ac287ab Feat periodic session checks (#2032) 2025-03-06 15:07:56 +01:00
01f05dacfb Merge pull request #2058 from teamhanko/fix-user-delete-webhook
fix: use TriggerWebhook function instead of NotifyUserChange
2025-02-25 15:37:20 +01:00
4187417f9a fix: use TriggerWebhook function instead of NotifyUserChange
The `NotifyUserChange` function tries to get the user from the database but since the user was deleted the user is not present anymore and therefore `nil` is returned. To fix it, the account delete event is triggered through `TriggerWebhook`.
2025-02-24 16:46:09 +01:00
63da219380 feat: introduce html mails (#2045) 2025-02-19 12:58:44 +01:00
983000d94e feat(ee): saml idp initiated sso 2025-02-13 12:44:36 +01:00
55d6efb879 feat: add webhook events and include IP address and user agent in event data (#2048) 2025-02-13 11:53:25 +01:00
e93788d774 feat: use exact template names for email.send webhook types 2025-02-11 19:07:46 +01:00
062aee4d45 fix: SAML issues (#2041)
Rename identities table columns for more clarity. Rename parameters,
arguments etc. to accommodate these changes.
    
Change that the SAML provider domain is persisted in the identities
table as the provider ID. Use the SAML Entity ID/Issuer ID of the
IdP instead.
    
Introduce saml identity entity (including migrations and a persister)
as a specialization of an identity to allow for determining the
correct provider name to return to the client/frontend and for assisting
in determining whether an identity is a SAML identity (i.e. SAML
identities should have a corresponding SAML Identity instance while
OAuth/OIDC entities do not).
2025-01-31 14:17:52 +01:00
7010db9081 feat: add username to session JWT and public session API responses 2025-01-30 12:58:08 +01:00
9836c48f72 fix: webhooks missing triggers and events
Add missing email create webhook trigger and add events and trigger 
calls for username changes. Update readme with missing/new webhook 
events.
2025-01-30 12:47:14 +01:00
ce9626dc2c fix: error handling when using zombie passkeys (#2034) 2025-01-29 09:49:03 +01:00
d66b267646 feat: add facebook provider (#2007)
* add sign in with facebook

* feat: add facebook provider to factory function

* feat: add facebook config defaults

* feat: use newest facebook api version

* feat: make facebook provider consistent with other providers

* feat: add check for email

We cannot assume a user always has a valid email.
Even though it is not the used "me" endpoint, see:

https://developers.facebook.com/docs/graph-api/reference/user/

* docs: elaborate comment

* fix: fix third party tests

* feat: add facebook icon

* feat: add appsecret_proof to requests w. access token

* refactor: build userinfo url programmatically

* feat: map all available name claims

---------

Co-authored-by: Prathamesh <psvagare@gmail.com>
2025-01-15 21:28:23 +01:00
5023a53980 feat: email i18n 2025-01-13 12:58:43 +01:00
c40897ac09 feat: always persist sessions server-side, config adjustments (#1997)
* feat: always persist sessions server-side, config adjustments
2024-12-20 09:52:52 +01:00
80680a26a4 chore: add same site attribute to the device trust cookie (#2006) 2024-12-13 13:30:33 +01:00
3961837c5c fix: return after suspending delete session action
Without a return the remaining code would be executed, expecting a session_id
in the context which is not present. This results in a panic.
2024-12-11 14:31:08 +01:00
21fd1d460f Feat custom user handle (#1978)
Add a custom user handle to a webauthn credential

---------

Co-authored-by: bjoern-m <56024829+bjoern-m@users.noreply.github.com>
2024-12-05 15:26:22 +01:00
455e8e3677 feat: third party custom providers
* feat: third party custom providers

- New configuration option `third_party.custom_providers`. `custom_providers`
  is a map of arbitrarily chosen keys to a `CustomThirdPartyProvider` - this is
  implemented as a new type differing from the existing configuration type
  `ThirdPartyProvider` used for built-in providers because they have different
  configuration requirements.

- Both `ThirdPartyProvider` and `CustomThirdPartyProvider` types get a non-
  configurable, automatically populated `Name` (during the config's `PostProcess`)
  that sort of serves as an identifier/slug for the provider in order to
  distinguish provider types at runtime.
    - A `CustomThirdPartyProvider`s `Name` is automatically prefixed during
      `PostProcess` with a "custom_" prefix to ensure that providers can be
      distinguished at runtime.
    - A (built-in) `ThirdPartyProvider`s `Name` is "hard-coded" through the
      `DefaultConfig`.

- Built-in OAuth/OIDC provider implementations are currently instantiated
  on-demand instead of once at appliation startup (i.e. unlike SAML
  providers) - i.e. when a user requests auth/authz with a third party
  provider, only then a provider is instantiated and created via factory
  function (`thirdparty.GetProvider`).  Custom providers follow this
  pattern, hence the factory function had to be adjusted to take into account
  providers with the aforementioned "custom_" prefix (i.e.: if it is a
  "custom_" provider, instantiate a `customProvider` implementation).

- The `customProvider` implementation uses the `go-oidc` library. Instances
  of providers of the type this library offers can be instantiated by passing
  in an `issuer` URL. Such an instantiation automatically attempts to retrieve
  an OIDC discovery document from a `.well-known` endpoint. This also performs
  an issuer validation. Providers configured to not use OIDC discovery (i.e.
  `use_discovery` in the `CustomThirdPartyProvider` is `false` or omitted) do
  not do this issuer check.

- The `customProvider` implementation is further based on the assumption that
  provider user data is only extracted from a userinfo endpoint response, i.e.
  in case of an OIDC provider, the implementation does not make use of the ID
  token - no validation is performed on the ID token.

- The `customProvider` implementation requires configuring a list of `scopes`:
  because the custom providers allow configuring both OAuth as well as OIDC
  providers, we cannot simply set a default set of scopes, e.g. `openid`, which
  is a required claim for OIDC - some providers return errors on unknown claims
  so setting this would make the third party auth process prone to errors.

- The `customProvider` implementation allows for a simple mapping of claims
  contained in the userinfo response from the provider to "known" standard OIDC
  conformant claims at the Hanko backend (defined in the `thirdparty.Claims`
  struct) through an `attribute_mapping` configuration option. The mapping is a
  simple one-to-one mapping, i.e. no complex mapping instructions are possible,
  e.g. mapping concatenations of multiple claims in the provider data source or
  similar. Any other non-standard claims returned by the provider are placed in
  a `custom_claims` attribute. Except for the user ID (`sub`), `email` and
  `email_verified` claims the third party functionality currently does not allow
  accessing this user data but there's a good chance this will change in the future,
  so I tried to make sure that any info retrieved from the provider is somehow
  preserved (it is persisted in the `data` column for an `identity` btw. and updated
  on every login with the provider).
    - I also noticed that the `thirdparty.Claims` were missing the `address` claim,
      so I added that for completeness' sake.

- The changes also fix a "bug" in the account `linking` logic whereby third party
  connections were established by simply assuming that the email retrieved from the
  provider was verified. So, even if the email address at the provider was not
  verified (or the provider simply did/does not provide info about the verification
  status) an account was created and/or linked and the flow API capabilities of
  automatically triggering a passcode if the backend was configured to require email
  verification would not take effect. This was a wrong assumption and the verification
  status is now based on the actual value retrieved from the provider.
- In case of a triggered passcode, the changes also modify the token exchange
   action to prevent showing a `back` button/link, since it does not make sense to
   go `back` to anything right after the token exchange - there is nothing to go
   "back" to.
2024-12-04 13:40:08 +01:00
f32f48e85b feat: trusted devices and 'remember me' (#1982) 2024-11-29 11:06:47 +01:00
36e3309076 fix MFA login with security key (#1968) 2024-11-07 12:25:02 +01:00
bc04b729dd feat: introduce mfa (#1645)
* feat: create otp_secrets table

* feat: create otp secret model

* feat: add mfa_only column to webauthn_credentials table

* feat: add mfa only field to webauthn credential model

* feat: add mfa config (#1607)

* feat: add otp secret persister (#1613)

* feat: MFA usage sub flow (#1614)

* feat: add mfa-usage sub-flow

---------

Co-authored-by: Lennart Fleischmann <67686424+lfleischmann@users.noreply.github.com>

* feat: include platform authenticator availybility in the preflight flow (#1615)

* feat: add mfa creation subflow

* feat: adjust registration flow

* feat: integrate mfa usage sub-flow

* feat: add pages for mfa (#1622)

* feat: profile flow adjustments for mfa support

* fix: suspension logic for mfa deletion actions

* feat: use dedicated action for security key creation options

* fix: mfa method stash entry can be stale on profile flow

The mfa_creation subflow sets an mfa_method stash value so that
when creating and persisting the credential the mfa_only flag can
be set correctly in the hook responsible for that. But the profile flow
never "ends" and and returns to the initial state so I can also
register a passkey afterwards. The mfa_method stash key remains on the
stash but is used in the hook nonetheless, so the passkey is incorrectly
recognized as a security key.

The mfa_method key is now deleted after successfully persisting the
credential/security_key. This should not have an effect on the login
flow because the mfa_creation subflow is the last subflow to be
executed. It also should not affect the registration flow, because the
hook is not applied in the registration flow (persistence of data is
all handled in the create_user hook).

* feat: add new icons and english translations (#1626)

* fix: credential id encoding corrected (#1628)

* feat: add audit logs for mfa creation

* feat: add a skip link to the mfa method chooser (#1630)

* feat: save the security key during login (#1629)

* feat: show security keys in profile

* feat: add authenticator app management to profile (#1633)

* feat: add authenticator app management to profile
* feat: passkey counts as second factor

* feat: prohibit security key first factor usage

* feat: add all WA creds to exclude list on registration

* refactor: mfa stash entries and webauthn credential persistence

Renames MFA stash entry for indicating usage (login) method to make its
meaning more explicit. Also removes code persisting a webauthn credential
from the attestation verification action in the onboarding flow because
this is already done by a shared hook.

* refactor: simplify WA creation call

Co-authored-by: bjoern-m <56024829+bjoern-m@users.noreply.github.com>

* chore: adjust mfa flow

* fix: mfa onboarding always shown during login

* fix: mfa onboarding not shown after password or email creation during login

* fix: mfa onboarding not shown without user detail onboarding

* fix: correct skip/back behaviour

* feat: reuse generated otp secret when the code is invalid

* chore: skip mfa prompt if the user only has a passkey

* chore: adjust login flow 

* chore: skip mfa prompt if the user only has a passkey

* chore: refactor and improve mfa onboarding

* fix: no mfa onboarding when passwords and passkeys are disabled

* fix: only show mfa onbooarding once

* feat: add a function to the flowpilot to check whether a state has been visited

* chore: adjust recovery flow (#1655)

* feat: disable password, passcode endpoints when mfa enabled

* Feat: remember last used login method (#1674)

* chore: remove omitempty from boolean (#1676)

* chore: improved error handling (#1679)

* chore: improved error handling

* feat: add missing translations (#1681)

* feat: update aaguid list (#1678)

* fix: do not suspend webauthn action for MFA (#1778)

Do not suspend the `webauthn_verify_attestation_response` action when passkeys are disabled, but security keys and MFA are enabled.

* fix: change texts (#1785)

Change texts regarding security creation to be more consistent across the flows and to be more precise.

* Fix: UI issues (#1846)

* fix: loading spinner alignment corrected

* fix: auth app deletion link is shown while deletion is not allowed

* Chore: remove test persister (#1876)

* chore: remove deprecated test persister

* chore: replace test persister calls

* chore: add saml state fixtures

* Update backend/flow_api/services/webauthn.go

Co-authored-by: Frederic Jahn <frederic.jahn@hanko.io>

* Update backend/dto/profile.go

Co-authored-by: Frederic Jahn <frederic.jahn@hanko.io>

* fix: otp validation uses the rate limiter key for passwords

* chore: add otp-limits to the default config

* chore: add explanation for 'UserVerification' setting on security keys

---------

Co-authored-by: Lennart Fleischmann <lennart.fleischmann@hanko.io>
Co-authored-by: Lennart Fleischmann <67686424+lfleischmann@users.noreply.github.com>
Co-authored-by: Frederic Jahn <frederic.jahn@hanko.io>
2024-11-01 19:38:30 +01:00
42b1c94719 fix: session delete action
Suspends the action if there is only one session and it is the same
as the current. Also now validates the allowed input values during
execution.
2024-10-17 17:42:03 +02:00
9dbc62524a feat: Server side sessions (#1673)
* feat: add server side sessions

* feat: add lastUsed & admin endpoint

* feat: add session list to elements

* fix: fix public session endpoint

* chore: only store session info when enabled

* build: update go mod

* feat: add translations

* test: fix tests

* feat: change path

* feat: return userID on session validation endpoint

* feat: move all session endpoints to public router

* fix: add missing translation

* fix: add missing structs

* chore: align session persister with other persisters

* fix: use correct translation label

* chore: add db validator to session model

* feat: create server side session from cmd

* fix: fix review findings
2024-10-15 11:36:32 +02:00
1ae7751599 fix(flow-api): use transaction in password service
see: 38a11deffaec8168093d94b8f0fb554dfee13dd3
2024-10-09 12:36:26 +02:00
5a10f8bef7 fix(flow-api): password update action
The action provides a password credential with the wrong id to
the update method of the password service - it uses a constructor
function for a password credential model, but this function
generates a new id instead of the id of the credential associated
with the user
2024-10-09 12:36:26 +02:00
b91e6cada4 fix: registration success hook execution order
Hook execution order is the reverse of the actual argument order,
so the issue session hook is run first and user creation is run
last. This leads to the issue session hook not having the full
data for the created user and hence the JWT also does not contain
email of the user. This commit changes the order so that the
issue session hook is run last.
2024-08-30 15:08:36 +02:00
38a11deffa fix: only use transaction connection in a transaction (#1598)
* fix: only use transaction connection in a transaction

* test: fix webhook tests
2024-08-28 11:56:09 +02:00
e72c1128ee fix: passcode invalid error not shown (#1594) 2024-08-26 18:15:24 +02:00
9ff845311c fix: create new flow for every request
Create a new flow for every request, because the flowBuilder is not save for concurrent usage.
2024-08-26 15:27:58 +02:00
92a8743c14 feat: update DTO with username field (#1583) 2024-08-23 11:12:46 +02:00
7c9c69f3b8 fix: send webhook on passcode resend 2024-08-13 16:57:40 +02:00
b203668178 fix: do not send emails when disabled
do not send emails when email_delivery.enabled is set to false
2024-08-13 16:57:40 +02:00
0835215654 chore: add webhooks to flow-api (#1574) 2024-08-13 16:00:52 +02:00
ed4f64f01b fix: hopefully fix thirdparty for cross-domain 2024-08-07 19:03:11 +02:00