- 0c52594: feat: added AUTH_REQUIRE_ELEVATED_CLAIM to require elevated permissions for certain action
- 93abd35: feat: added endpoint to "elevate" permissions using webauthn
- fcec7fa: chore: update dependencies
- 27aeca6: fix: replace helper.error with helper.message due to joi's breaking changes
- 68aa985: chore: add pnpm audit to the CI and update deps
- 00b3994: Adding an index on refresh_tokens to increase performances
- 011516e: fix: parse stringified metadata during oauth callback
- 634f2bf: feat: add
AUTH_WEBAUTHN_RP_ID
environment variable
- 2e3096c: fix: conceal error if AUTH_CONCEAL_ERRORS is set
- cd8c786: feat: add option to disable user sign-up through
AUTH_DISABLE_SIGNUP
- 003cfd6: fix: make sure existing modified permissions are not overwritten
- 15459a9: fix: use empty as AUTH_API_PREFIX default value
- ffba7d8: fix: move catch-all route-not-found handler to root
- b727ab9: fix: update sign-in with Linked-In to use OpenId
- 024258c: feat: set oauth origin dynamically based on host header
- 5663eec: feat: allow configuring api prefix
- 044ed00: fix: mount oauth and healthz routes correctly when specifying AUTH_API_PREFIX
- 2aa0d6d: fix(oauth): correctly parse user profile during Sign-In with Apple
- 59e588a: added codeql
- 4eff7f4: fix: send back refresh token upon sign-in with pat
- ca5010d: fix: merge new select/delete permissions with the existing ones
- 840d730: feat(smtp): make the
X-SMTPAPI
header configurable
- ceaca45: chore(node): bump Node.js to v18
- 1706c37: fix(redirect): generate valid redirection links
- ceaca45: chore(logs): improve logging in production
- 60dcbf4: fix(email-templates): correct typos in the French translation
- 0cc9d36: fix: don't crash when adding allowed roles upon sign-in with a provider
- d412a93: feat: add
refreshTokenId
to session
-
50a1b1d: chore: migrate
refresh_token
column toid
⚠️ Warning: This is a breaking change.We've renamed the
refresh_token
column toid
. While this change will improve the functionality of Hasura Auth, it may cause issues for any permissions or relationships that were using the oldrefresh_token
column.Please note that any permissions or relationships that were using the
refresh_token
column will be affected by this change. If you're using therefresh_token
column in any way, you'll need to update your code to use the newid
column and ensure that your app works as expected.
- 29eff81: fix(oauth): be more verbose when a provider fails
- 5529f7d: fix(pat): replace enum type with an enum table to fix issues with PAT creation
- 005e259: chore(logs): add
AUTH_SHOW_LOG_QUERY_PARAMS
environment variable to control query parameter visibility
- 9a7e027: chore(logs): add masked headers and query parameters to logs
- 11e1eb3: feat(pat): allow users to create personal access tokens
- 73b7642: Introduce support for using wildcards with redirect URLs
-
f7ec32f: Revert #317 (connect directly to postgres)
We are reverting #317 because of issues we found with connections being exhausted on the database side. Having hasura-auth connect directly means that we have to consider/tweak an additional connection pooler. It also makes things a bit more cumbersome, operationally speaking, when provisioning projects in the cloud.
The initial goal of #317 was to allow users to choose the naming convention to use with hasura. We have found that using hasura's run_sql, available through its schema API (https://hasura.io/docs/latest/api-reference/schema-api/run-sql/#schema-run-sql), allows for the same naming flexibility while funneling all connections through the same entry point.
- 2eadfa9: Fix validation for redirectUrl
-
45afb45: Stop sending the refresh token in the hash part of the redirection
Originally, hasura-auth was adding the refresh token to the hash part of the redirection urls, but we decided to add it to the query parameters, as the hash was not accessible in SSR pages. We decided to add the refresh token in both places during a transition period in order to prevent a breaking change with legacy versions of the SDK, that were looking for the refresh token in the hash. However, since
@nhost/[email protected]
(April), the SDK also finds (and removes) the refresh token in both places.Sending the refresh in the hash has a significant impact on Vue users, as the vue-router is handling routes in the hash part of the url in its own way that conflicts with the urls sent by hasura-auth.
This is a breaking change for clients using previous versions of the SDK, or manually looking for the refresh token in the hash instead of the query parameter
-
d5eed8f: Use SQL instead of GraphQL to interact with the DB
Run DB operations through SQL rather than GraphQL, so the user can pick any Hasura naming convention configuration they want.
As the SQL operations are simpler than the ones generated by Hasura, and as we don't use Hasura anymore to proxy DB operations, it also comes with a slight performance increase.
Hasura-auth now only uses the GraphQL API to generate custom claims.
-
2e15427: Introduce a new
refresh_tokens.refresh_token_hash
column.Preparatory work to store refresh tokens as a SHA256 hash.
To avoid a breaking change, the
refresh_tokens.refresh_token
column remains unchanged until the next major release.- The
refresh_tokens.refresh_token
column is now deprecated. - The hashed refresh token is a Postgres stored generated column.
- The internal GraphQL queries are using the hashed refresh token.
- The internal GraphQL mutations are still updating the
refresh_token
column.
When introducing the breaking change, we will:
- Rename
refresh_tokens.refresh_token
torefresh_tokens.id
. - Use the
id
column as an identifier. - Remove the
generated
expression in therefresh_token_hash
column. - New refresh tokens will then be saved uniquely as SHA256.
- The
-
de0b163: Added spanish email templates, thanks @JepriCreations for the contribution
-
b398ae2: A custom claim that is expected to be an array (ie. contains "[]" in its path) will be set to an empty array - instead of being undefined - when its query returns no value.
This allows permissions of the form "something IN X-Hasura-myCustomClaimArray" to work as intended when the array is empty.
-
87a3e96: Added czech email templates, thanks @suplere for the contribution
-
fff9d1f: Added bulgarian email templates, thanks @azlekov for the contribution
-
5a224e6: Improve the logging of the SMTP errors
When an email could not be sent, the logs where too limited. As a result, it was not possible to know the reason why emails could not be sent, nor knowing why hasura-auth was returning an HTTP 500 error.
When an email can't be sent, hasura-auth now adds two more lines to the logs before the standard http log row:
{"address":"127.0.0.1","code":"ESOCKET","command":"CONN","errno":-61,"level":"warn","message":"SMTP error","port":1026,"syscall":"connect"} {"level":"warn","message":"SMTP error context","template":"email-verify","to":"[email protected]"} {"latencyInNs":271000000,"level":"error","message":"POST /signup/email-password 500 271ms","method":"POST","statusCode":500,"url":"/signup/email-password"}
-
f85e92d: - The default role is now automatically added to the allowed roles.
- The default locale is now automatically added to the allowed locales.
Previously, it was explicitly required to add the
me
andAUTH_USER_DEFAULT_ROLE
roles toAUTH_USER_DEFAULT_ALLOWED_ROLES
. They are now automatically added toAUTH_USER_DEFAULT_ALLOWED_ROLES
.Before:
AUTH_USER_DEFAULT_ROLE=user AUTH_USER_DEFAULT_ALLOWED_ROLES=user,me,other
Now, the following configuration will also work:
AUTH_USER_DEFAULT_ROLE=user AUTH_USER_DEFAULT_ALLOWED_ROLES=other
Both syntaxes will allow the roles
user
,me
, andother
.Similarly, it is no longer a requirement to add the value of
AUTH_LOCALE_DEFAULT
to theAUTH_LOCALE_ALLOWED_LOCALES
.Before:
AUTH_LOCALE_DEFAULT=en AUTH_LOCALE_ALLOWED_LOCALES=en,fr
Now, the following configuration will also work:
AUTH_LOCALE_DEFAULT=en AUTH_LOCALE_ALLOWED_LOCALES=en,fr
Both syntaxes will allow the locales
en
andfr
. -
02da92a: Allow WorkOS organization/domain/connection from the query parameters
The Grant
dynamic
parameter was not correctly set. Moreover, the Oauth routes were usingexpress.use
instead ofexpress.all
. As a result. the routes defined for${OAUTH_ROUTE}/:provider
where also matching an url like${OAUTH_ROUTE}/:provider/callback
, although they shouldn't have.
-
951349b: Optionally conceal sensitive error messages
Introduce a new
AUTH_CONCEAL_ERRORS
environment variable that conceals error messages to avoid leaking indirect information about users e.g. a user is registered in the application or a given password is invalid.It is disabled by default.
-
d3fe853: Preserve the Oauth session between the initial request and the callback
Fixes nhost/nhost#1353
-
9c25b1f: Ability to set test phone numbers for phone auth
This can be used without any provider set. When sign in via phone auth using a test phone number is invoked the SMS message with the verification code will be available trough the logs. This way you can also test your SMS templates.
-
e0949d7: Try the first characters of the Oauth user profile's locale
Some Oauth providers returns locales. But it can be
en-GB
whereas hasura-auth only accepts locales coded in two characters. It now tries to validate the two first characters of the user profile locale against the list of allowed locales. -
e0949d7: Don't fail WorkOS transformation when the user profile is incorrect
When not configuring WorkOS correctly, the
raw_attributes
of the user profile could be null. This fix avoids returning an error when accessing properties of this object that would be null. -
e0949d7: Correct validation of custom locale and redirect urls in Oauth routes
- 42d7ce8: Fix Oauth redirection
-
09478c4: Allow patterns in allowed urls
AUTH_ACCESS_CONTROL_ALLOWED_REDIRECT_URLS
now accepts wildcard and other micromatch patterns inAUTH_ACCESS_CONTROL_ALLOWED_REDIRECT_URLS
.To match
https://(random-subdomain).vercel.app
:AUTH_ACCESS_CONTROL_ALLOWED_REDIRECT_URLS=https://*.vercel.app
As a result:
# Correct https://bob.vercel.app https://anything.vercel.app # Incorrect https://sub.bob.vercel.app http://bob.vercel.app https://vercel.app
It is possible to use other patterns, for instance:
- to allow both http and https:
AUTH_ACCESS_CONTROL_ALLOWED_REDIRECT_URLS=http?(s)://website.com
- to allow any port:
AUTH_ACCESS_CONTROL_ALLOWED_REDIRECT_URLS=http://website.com?(:{1..65536})
-
4d16514: Fix Twitter provider (close #100)
-
c6daab9: Synchronise
AUTH_USER_DEFAULT_ALLOWED_ROLES
andAUTH_USER_DEFAULT_ROLE
with the database When starting the server, all the roles defined inAUTH_USER_DEFAULT_ALLOWED_ROLES
andAUTH_USER_DEFAULT_ROLE
are upserted into theauth.roles
table -
4d16514: Use Grant Hasura Auth was relying on PassportJS and numerous npm packages to orchestrate each Oauth provider. The code became complex to maintain, and it became more and more difficult to add new providers. Providers are noew defined in one single file so it is easier to add new ones.
- 4d16514: Fetch the user locale when available (Discord, Google, LinkedIn, WorkOS)
- 4d16514: Fetch avatar url from BitBucket
- 4d16514: Fetch display name from the Strava provider
- c6daab9: Redirect Oauth errors or cancellations When a user cancelled their authentication in the middle of the Oauth choregraphy, they were falling back to an error on the Hasura Auth callback endpoint. Hasura Auth now parses the error and redirect the user to the client url, with error details as query parameters.
- 4d16514: The service starts when a provider is incorrectly configured. Instead, the endpoint fails with a standard error. The error is logged (warn level)
- 4d16514: Fetch the email verification status when available (Apple, BitBucket, Discord, GitHub, Google)
- c6daab9: Preserve the case in
redirectTo
options, and case-insensitive validation TheredirectTo
values were transformed into lower case. It now validates regardless of the case, and preserve the original value. - c6daab9: Return Have I Been Pwned error message Hasura Auth now returns the reason why the password is not compliant with HIBP.
- c6daab9: Log error when failing to apply Hasura metadata
- c6daab9: Tell why Hasura can't be reached When starting, Hasura Auth waits for Hasura to be ready. Hasura Auth now logs the reason why Hasura can't be reached.
- 4d16514: Enforce Oauth scopes required by hasura-auth Custom scopes set as environment variables don't replace the scopes that are required by Hasura-auth to function. They are appended instead.
- c6daab9: Increase OTP secret entropy to 256 bits
0.15.0 (2022-10-18)
- 🐛 capture unhandled errors (c1f82c4)
- 🐛 remove wrong email-template warning (8972912), closes #168
- use the metadata column in custom claims (179d96a)
- 🎸 Improve logging (4bccab8)
- 🎸 improve metadata application and startup time (728f35b)# 0.14.0 (2022-10-07)
- provider: add azure ad provider (c7247cc)## 0.13.2 (2022-09-28), thanks @yannickglt for the contribution
- Rename
authenticators
tosecurity keys
in the DB and GraphQL schemas - Fetch profile from WorkOS oauth connection (b49d4f7)
- Use client hostname as RP ID (2371fdc)
- webauthn signup endpoints (8982a49)# 0.12.0 (2022-09-16)
- 🐛 deprecate AUTH_EMAIL_TEMPLATE_FETCH_URL (4067c03)
- 🐛 don't add custom claims when null/undefined values (7a129f6)
- 🐛 don't break reditection with redirectTo and params (3e55b9e), closes #233
- broaden WebAuthn authenticators & algorithms (bdff4fe)
- send id+nickname when adding a security key (f2cb098)
- webauthn: use the hostname of
AUTH_SERVER_URL
as a default relying party (7f3944d) - webauthn: use the server url hostname as RP (50126b4)
- remove webauthn signup endpoints (224e990)
- webauthn: add optional authenticator nickname (457fafd)
- workos oauth provider (ab35971)# 0.10.0 (2022-07-13)
- Quote "OK" HTTP responses so auth endpoints can be used in Hasura Actions(5e7b6e0)
- Remove SQL comment on the
auth
schema as migration scripts should work even if the Postgres user does not own theauth
(6daeeee) - webauthn: disable unauthorized add of subsequent authenticator (077bd17)
0.9.3 (2022-06-30)
- do not add null values to custom claims (35bf186)
- use the metadata field in custom claims (a7072d9)
- Fix the Apple Oauth provider: #154
- SQL comments on schema, tables, and colums (aeea1d3)
0.9.2 (2022-06-22)
- forbid anonymous users to change email or password, or to activate MFA (064b15b
0.9.1 (2022-06-14)
- add
displayName
,email
, andnewEmail
variables to all email templates (d2235e9) - do not actually follow redirection when redirectTo is invalid (7d24e55)
- workaround for outlook safelinks: add
HEAD
operation to the/verify
route (1f12a53), closes #189
0.9.0 (2022-06-02)
- validate phone number and transform them in the international format (70edaca)
- allow any
redirectTo
when noAUTH_CLIENT_URL
is set (73c0262)
- Able to use both phone number and messaging service id as
from
This way users can use both a simple phone number without setting up a Twilio messaging service or use a messaging service from Twilio (doc).
0.8.0 (2022-05-24)
- token: reuse and update expiration date of a valid refresh token instead of invalidating it and creating a new one (7583997), closes #65
- check locales are not more than two characters (e2eac38)
- check the new email is not already in use before changing it (0436574)
- return standard error codes in sms passwordless sign-in (74087dd)
- Verify Twillio configuration before using it
- Don't delete the user if sending message with Twillio fails, closes #79
- Check user is active when authenticating with SMS passwordless, closes #99
- Revert "Return signIn responses for passwordless" (363bbbc)
0.7.1 (2022-04-28)
- use query parameter instead of hash when adding the refresh token to an url (af8ea50)
0.7.0 (2022-04-27)
- don't fail when unknown options are present in the query parameters (3bf88d8)
- use encoded
redirectTo
url value in email templates (9b88a91)
0.6.3 (2022-04-21)
- filter internal user fields in session (d1c4c9b)
0.6.2 (2022-04-20)
- revert 00002 migration name to previous name when migration fails because of it (6a0856a)
0.6.1 (2022-04-20)
- allow
redirectTo
option to start with anyAUTH_ACCESS_CONTROL_ALLOWED_REDIRECT_URLS
value (dac0332) - correct redirectTo and fall back to AUTH_CLIENT_URL if the
redirectTo
option is invalid (2e1819d), closes #137 - remove the AUTH_HOST environment variable (cacce97), closes #139
- run a metadata reload before and after applying hasura-auth metadata (bd9b361)
- improve logging on startup (c172c8a)
- improve startup with async imports (e00c073)
- set AUTH_CLIENT_URL and AUTH_ACCESS_CONTROL_ALLOWED_REDIRECT_URLS to lower case (8bb351d)
0.6.0 (2022-04-06)
- change default refresh token expiration to 30 days (a2e0d2a), closes #48
- rename JWT claim
x-hasura-isAnonymous
tox-hasura-is-anonymous
(a4ca42e), closes #126
- add
emailVerified
,phoneNumber
,phoneNumberVerified
, andactiveMfaType
to User (4d452d7)
0.5.0 (2022-03-31)
Error messages were either sent as string or as an object (other errors). Moreover, the request payload validation was performed in two separate places in the code, as and a result, it was not possible to predict if payload validation errors were sent as a string or an object. In addition, error codes and messages were inconsistent or missing from one endpoint to another, given the same type of error.
All errors sent back to the client now follow the same format:
{
error: string; // machine-readable error code
status: number; // http status
message: string; // human-readable message
}
The list of errors is comprehensive and available here.
Until now, endpoints that were redirecting the user to the frontend client were stopping redirection when an error occurred. It lead to bad user experience as users where stopped on a
In all the endpoints that have a redirectTo
option, errors are now instead passed on to the frontend client as a query parameter, so the frontend can handle these errors and guide the user accordingly.
The two following keys are added to the query string:
error
: machine-readable error codeerrorDescription
: human-readable message
Email were not validated when authenticating with an Oauth provider. When the Oauth provider calls back to Hasura Auth, users with an email that don't follow the rules determined by AUTH_ACCESS_CONTROL_ALLOWED_EMAILS
, AUTH_ACCESS_CONTROL_ALLOWED_EMAIL_DOMAINS
, AUTH_ACCESS_CONTROL_BLOCKED_EMAILS
and AUTH_ACCESS_CONTROL_BLOCKED_EMAIL_DOMAINS
are now not able to complete authentication.
Closes #84
The validation of allowedRoles
were failing when passed on as an option.
Closes #116
This release comes with improvements in the code structure and readiblity:
- Request payload validation is consistently done by Joi prior to the handling of the endpoint logic
- The payload validation rules have been move to each route file, instead of putting them all in the same place
- Http status codes and messages are not hard coded anymore, but are writtent with
http-status-codes
- Helpers and utils files are restructured in a more sensible way, and exported/imported in the ESM way
- Dead code and uneless/stale comments have been removed
0.4.3 (2022-03-18)
0.4.2 (2022-03-15)
0.4.1 (2022-03-15)
0.4.0 (2022-03-14)
0.3.2 (2022-03-09)
- patch twitch Oauth provider (1cd9926)undefined
0.3.1 (2022-03-04)
- use process.env.npm_package_version instead of import 'package.json' (ab23184)
0.3.0 (2022-03-02)
- add openapi/swagger endpoint (6b92546)
- add Twitch and Discord Oauth providers
0.2.1 (2022-02-18)
- reload metadata after applying metadata changes (26fb2ff)
0.2.0 (2022-02-03)
Hasura comes with a powerful authorisation system. Hasura Auth is already configured to add x-hasura-user-id
, x-hasura-allowed-roles
, and x-hasura-user-isAnonymous
to the JSON Web Tokens it generates.
This release introduces the ability to define custom claims to add to the JWT, so they can be used by Hasura to determine the permissions of the received GraphQL operation.
Each custom claim is defined by a pair of a key and a value:
- The key determines the name of the claim, prefixed by
x-hasura
. For instance,organisation-id
will becomex-hasura-organisation-id
. - The value is a representation of the path to look at to determine the value of the claim. For instance
[profile.organisation.id](http://profile.organisation.id)
will look for theuser.profile
Hasura relationship, and theprofile.organisation
Hasura relationship. Array values are transformed into Postgres syntax so Hasura can interpret them. See the official Hasura documentation to understand the session variables format.
AUTH_JWT_CUSTOM_CLAIMS={"organisation-id":"profile.organisation[].id", "project-ids":"profile.contributesTo[].project.id"}
Will automatically generate and fetch the following GraphQL query:
{
user(id: "<user-id>") {
profile {
organisation {
id
}
contributesTo {
project {
id
}
}
}
}
}
It will then use the same expressions e.g. profile.contributesTo[].project.id
to evaluate the result with JSONata, and possibly transform arrays into Hasura-readable, PostgreSQL arrays.Finally, it adds the custom claims to the JWT in the https://hasura.io/jwt/claims
namespace:
{
"https://hasura.io/jwt/claims": {
"x-hasura-organisation-id": "8bdc4f57-7d64-4146-a663-6bcb05ea2ac1",
"x-hasura-project-ids": "{\"3af1b33f-fd0f-425e-92e2-0db09c8b2e29\",\"979cb94c-d873-4d5b-8ee0-74527428f58f\"}",
"x-hasura-allowed-roles": [ "me", "user" ],
"x-hasura-default-role": "user",
"x-hasura-user-id": "121bbea4-908e-4540-ac5d-52c7f6f93bec",
"x-hasura-user-is-anonymous": "false"
}
"sub": "f8776768-4bbd-46f8-bae1-3c40da4a89ff",
"iss": "hasura-auth",
"iat": 1643040189,
"exp": 1643041089
}
A basic JSONB column in the auth.users
table, that is passed on as an option on registration:
{
"email": "[email protected]",
"passord": "12345678",
"options": {
"metadata": {
"first_name": "Bob"
}
}
}
When running Hasura Auth in its own infrastructure, it is possible to mount a volume with custom email-templates
directory. However, in some cases, we may want to fetch templates from an external HTTP endpoint. Hence the introduction of a new AUTH_EMAIL_TEMPLATE_FETCH_URL
environment variable:
AUTH_EMAIL_TEMPLATE_FETCH_URL=https://github.com/nhost/nhost/tree/custom-email-templates-example/examples/custom-email-templates
In the above example, on every email creation, the server will use this URL to fetch its templates, depending on the locale, email type and field.
For instance, the template for english verification email body will the fetched in https://raw.githubusercontent.com/nhost/nhost/custom-email-templates-example/examples/custom-email-templates/en/email-verify/body.html.
See the example in the main nhost/nhost repository.
The context variables in email templates have been simplified: the ${link}
variable contains the entire redirection url the recipient needs to follow.
- allow redirect urls in Oauth that starts with the one defined in the server (c00bff8)
- email-templates: fallback to the default template when the requested template doesn't exist (6a70c10)
- email-templates: use the locale given as an option, then the existing user locale, then default (31d4a89)
- metadata: show column values when the column name is the same as the graphql field name (a595941), closes #76
- passwordless: don't send passwordless email when the user is disabled (3ec9c76)
- remove email-templates endpoint (5c6dbf5), closes #75
- custom claims (01c0207), closes #49
- implement remote email templates with AUTH_EMAIL_TEMPLATE_FETCH_URL (2458651)
- simplify email templates context (b94cdf2), closes #64
- use array custom JWT claims (53a286a)
- deactivate the
/email-templates
endpoint
0.1.0 (2022-01-18)
- Update README.md (#27) (f51bb26)
- better error message for redirectTo (#59) (0b76425)
- everything (da8c954)
- keep .env for dev in repo and updated hasura version to m1 supported image (#60) (394d4ae)
- password: validate password on change (#58) (994af31)
- user: fix user schemas (#52) (c7eb721)
- reduce docker image from 477MB to 176MB (5f4d2b2)