@ronn316 if you want to use silent mode during the upgrade
https://fusionauth.io/docs/get-started/download-and-install/silent-mode
@ronn316 if you want to use silent mode during the upgrade
https://fusionauth.io/docs/get-started/download-and-install/silent-mode
@itai This is what exists today, the team is working on more features for webhooks in upcoming releases.
FusionAuth provides certain guarantees when it comes to the delivery of webhooks. These guarantees are determined by the transaction level that you set for your webhooks. The transaction level can be one of the following:
"No webhooks are required to succeed": In this case, FusionAuth will "fire and forget" the webhooks. Even if all webhooks fail, the operation (like a user update) will still succeed (source).
"Any single webhook must succeed": If at least one webhook succeeds, the operation will succeed. If all webhooks fail, the operation will fail. FusionAuth will retry failed webhooks up to three additional times (source).
"All webhooks must succeed": Every single webhook must succeed for the operation to succeed. If any webhook fails, the operation will fail (source).
In case of failures, FusionAuth will retry sending the payload up to three additional times. If a webhook endpoint times out, this is considered a failure, the same as if a non 2xx
status code is returned. If the endpoint does not respond after the retries, the failure will be logged in the system log (source).
It's important to note that if a webhook is transactional and returns a non 2xx
status code, the corresponding action will not succeed. For example, if a user login triggers a webhook and the webhook fails, the user won’t be able to log in (source).
JavaMail settings in FusionAuth can be configured under the SMTP settings of a tenant. You can access these settings by navigating to Tenants > Edit > Advanced > SMTP settings
. Here, you can add additional properties for JavaMail.
For example, to enable debug mode, you can add mail.debug=true
to the additional properties. This will provide more verbose logging for SMTP, which can be helpful for troubleshooting email issues. The debug logs can be viewed under System > Logs
and selecting fusionauth-app.log
source.
In some cases, you might need to set timeouts for the SMTP connection. This can be done by adding the following properties:
mail.smtp.connectiontimeout=2000
mail.smtp.timeout=2000
These settings will set the read and write timeouts to 2 seconds (2000 ms) source.
If you're experiencing issues with email delivery, it might be helpful to change the SMTP port or switch between TLS and SSL, especially if you're using a cloud service like FusionAuth Cloud, which has certain restrictions on ports source.
Remember to be cautious when enabling debug mode or changing other settings, as it could potentially lead to a large volume of logs or affect the performance of your application.
@evanm Yes you can use the sub
inside of the JWT when making any API call to your backend. In your database this will be a unique Id for the user. You can even get more details about the user from FusionAuth by calling the User endpoints.
@richard-0 do you have a sample repo you could share, or your full config for the SDK?
@ronn316 I believe there was an database change that was required in 1.50 https://fusionauth.io/docs/release-notes/#version-1-50-0
You will need to check the upgrade info
https://fusionauth.io/docs/operate/deploy/upgrade
specifically the database migration in silent mode
https://fusionauth.io/docs/operate/deploy/upgrade#downtime-and-database-migrations
I do this all the time and keep meaning to create a post on codingcat.dev for it instead of hitting Jeff's site for it all the time. In the meantime I would suggest checking this out it always works for me
@evanm I would recommend using a JWT in your API and storing the user id to associate the user to your stripe user account.
You can find more about this in our tokens docs, here you will want the sub.
https://fusionauth.io/docs/lifecycle/authenticate-users/oauth/tokens
On point two it is a classic it depends scenario. This could be handled by logic that you build, or if it makes sense you could use FusionAuth's groups or entities
@tvdlooy were you able to resolve this?
@zaalbarxx sorry for the delay. I might be missing it (sorry not a PHP person) but I don't see where that confusion comes into play. I know that some of our docs had to get updated because of a change that we made during our 1.50 release that required to request further details in our scopes request.
This release makes significant changes to the default behavior of new Applications with regard to scopes in OAuth workflows. The database migration will update existing Applications to behave in a backwards compatible manner. See the OAuth Scopes documentation for more information, in particular the
Relationship
,Unknown scope policy
, andScope handling policy
configurations.
https://fusionauth.io/docs/release-notes/#version-1-50-0
Let me know if that still isn't making sense, or if there is a spot you were hung up on and I would be happy to update our docs. Or even better feel free to add a PR.
@zaalbarxx During this time did your FusionAuth version change with the Terraform update? Possibly pulling the latest image?
You can read more about the differences of the cookies set in our hosted backend documentation.
Cookies Set By the Hosted Backend
Name | HttpOnly | Description |
---|---|---|
app.at | true | The access token for the configured application. This is a JWT and can be presented to your APIs to access data and functionality. |
app.rt | true | The refresh token for the configured application. Only present if the offline_access scope is requested. This can be presented to FusionAuth to retrieve a new access token. |
app.idt | false | The Id token for the user for the configured application. Only present if the openid scope is requested. This is a JWT and can be accessed by JavaScript to display user account information. |
app.at_exp | false | The unix epoch timestamp indicating when the access token will expire. This can be checked by JavaScript to determine when a refresh token should be used to get a new access token. |
As you have called out the two tokens are meant for two different purposes.app.idt
is available to the browser using JavaScript and app.idt
is available only on calls that involve the server.
During true OAuth (not utilizing openid) you will not see email utilized. This is still valid for checking if a user is authenticated. You can send this to all of your API endpoints as well.
@didier just want to make sure my head is in the right place for what you are looking for
You can query for entities
curl -v -H 'Authorization: xHDJZOeZ3fbWmUxnx0vw2gNpyIXEcRfVQ-AnXcNo7_IzL5EM4kFBO2VC' \
'https://local.fusionauth.io/api/entity/search?queryString=name:*entity*'
Result
{
"entities": [
{
"clientId": "e3efa4bc-516b-4bf5-bb3e-9eb8aba62a61",
"clientSecret": "3fqDmUNpn7ZvesvBaiejHGoSyCDyrhlcy7MOOmLWdRI",
"data": {},
"id": "e3efa4bc-516b-4bf5-bb3e-9eb8aba62a61",
"insertInstant": 1715351523408,
"lastUpdateInstant": 1715351523408,
"name": "entity1",
"tenantId": "1c7aee2d-29c5-a4a7-c48f-91e56a777ea0",
"type": {
"data": {},
"id": "00c934d5-15b8-4bbf-a8cd-01b9ad048ae5",
"insertInstant": 1715351513399,
"jwtConfiguration": {
"enabled": false,
"timeToLiveInSeconds": 60
},
"lastUpdateInstant": 1715351513399,
"name": "alex-entity-type",
"permissions": [
{
"data": {},
"id": "0fe89220-0fd4-4f30-b127-1b23c9f6b75a",
"insertInstant": 1715351513400,
"isDefault": false,
"lastUpdateInstant": 1715351513400,
"name": "ALex"
}
]
}
},
{
"clientId": "48d8814f-1914-4a3d-9a55-3db4e34ba24d",
"clientSecret": "L9gT2dHHtEFS7-TBRIvRyKtnaV2Qu-oWP2aJKrQjgzk",
"data": {},
"id": "48d8814f-1914-4a3d-9a55-3db4e34ba24d",
"insertInstant": 1715351532089,
"lastUpdateInstant": 1715351532089,
"name": "entity2",
"tenantId": "1c7aee2d-29c5-a4a7-c48f-91e56a777ea0",
"type": {
"data": {},
"id": "00c934d5-15b8-4bbf-a8cd-01b9ad048ae5",
"insertInstant": 1715351513399,
"jwtConfiguration": {
"enabled": false,
"timeToLiveInSeconds": 60
},
"lastUpdateInstant": 1715351513399,
"name": "alex-entity-type",
"permissions": [
{
"data": {},
"id": "0fe89220-0fd4-4f30-b127-1b23c9f6b75a",
"insertInstant": 1715351513400,
"isDefault": false,
"lastUpdateInstant": 1715351513400,
"name": "ALex"
}
]
}
}
],
"nextResults": "eyJscyI6WyIxLjI4NzY4MiIsImVudGl0eTIiLCI0OGQ4ODE0Zi0xOTE0LTRhM2QtOWE1NS0zZGI0ZTM0YmEyNGQiXSwicXMiOiJuYW1lOiplbnRpdHkqIn0",
"total": 2
}
Then any/all entities that you want to get grants for you can call
curl -v -H 'Authorization: xHDJZOeZ3fbWmUxnx0vw2gNpyIXEcRfVQ-AnXcNo7_IzL5EM4kFBO2VC' \
'https://local.fusionauth.io/api/entity/e3efa4bc-516b-4bf5-bb3e-9eb8aba62a61/grant'
Result gives you back all associated users that have this granted.
{
"grants": [
{
"data": {},
"entity": {
"clientId": "e3efa4bc-516b-4bf5-bb3e-9eb8aba62a61",
"clientSecret": "3fqDmUNpn7ZvesvBaiejHGoSyCDyrhlcy7MOOmLWdRI",
"data": {},
"id": "e3efa4bc-516b-4bf5-bb3e-9eb8aba62a61",
"insertInstant": 1715351523408,
"lastUpdateInstant": 1715351523408,
"name": "entity1",
"tenantId": "1c7aee2d-29c5-a4a7-c48f-91e56a777ea0",
"type": {
"data": {},
"id": "00c934d5-15b8-4bbf-a8cd-01b9ad048ae5",
"insertInstant": 1715351513399,
"jwtConfiguration": {
"enabled": false,
"timeToLiveInSeconds": 60
},
"lastUpdateInstant": 1715351513399,
"name": "alex-entity-type",
"permissions": [
{
"data": {},
"id": "0fe89220-0fd4-4f30-b127-1b23c9f6b75a",
"insertInstant": 1715351513400,
"isDefault": false,
"lastUpdateInstant": 1715351513400,
"name": "ALex"
}
]
}
},
"id": "e87a00c3-e116-464d-83d3-cdfde0e27efc",
"insertInstant": 1715353110056,
"lastUpdateInstant": 1715353110056,
"permissions": [
"ALex"
],
"userId": "847506b4-186e-4ee0-be24-e87c579a8625"
},
{
"data": {},
"entity": {
"clientId": "e3efa4bc-516b-4bf5-bb3e-9eb8aba62a61",
"clientSecret": "3fqDmUNpn7ZvesvBaiejHGoSyCDyrhlcy7MOOmLWdRI",
"data": {},
"id": "e3efa4bc-516b-4bf5-bb3e-9eb8aba62a61",
"insertInstant": 1715351523408,
"lastUpdateInstant": 1715351523408,
"name": "entity1",
"tenantId": "1c7aee2d-29c5-a4a7-c48f-91e56a777ea0",
"type": {
"data": {},
"id": "00c934d5-15b8-4bbf-a8cd-01b9ad048ae5",
"insertInstant": 1715351513399,
"jwtConfiguration": {
"enabled": false,
"timeToLiveInSeconds": 60
},
"lastUpdateInstant": 1715351513399,
"name": "alex-entity-type",
"permissions": [
{
"data": {},
"id": "0fe89220-0fd4-4f30-b127-1b23c9f6b75a",
"insertInstant": 1715351513400,
"isDefault": false,
"lastUpdateInstant": 1715351513400,
"name": "ALex"
}
]
}
},
"id": "6c2cced6-22a9-49c9-984c-e55b47d6a5a5",
"insertInstant": 1715351571320,
"lastUpdateInstant": 1715351571320,
"permissions": [
"ALex"
],
"userId": "556e3f28-b9fe-4c62-bd6e-02ef3dec1c43"
}
]
}
Would that work?
@qwandery I was just having this discussion yesterday in this thread and also internally.
I think what we are missing for a FusionAuth guide is a SPA with multiple custom backend API implementations.
and possibly
Multiple SPA Applications hitting multiple backend API implementations.
We have both of these examples individually.
and in meta frameworks that create their own API's
but what I think we are missing is a full picture. For sure noted and have it on our backlog to create!
@qwandery I know we have a lot of examples and they are usually only a single language / framework. Would it be helpful to put together something where we have an Angular frontend with a .NET Core backend for something like a TODO list?
There are more examples listed here as well, but my guess is that you will have the same issue, of not blending two different frameworks.
@alan-rutter this is for sure an architectural decision, but you can use angular for the authentication side of the house, or you could pass that through your backend first.
I think what you are looking for is the former though where you are going to connect the application and it will set the cookie app.at
which has the access token
for the configured application. This is a JWT and can be presented to your APIs to access data and functionality.
Read more about that here: https://fusionauth.io/docs/apis/hosted-backend#prerequisites
With using our Angular SDK you will get a HttpOnly Cookie set app.at
that will have the user information that you are looking for when making calls to your .NET Core API you can find these directly in those cookies as they are available within the header of a server call.
https://fusionauth.io/docs/sdks/angular-sdk
If you make calls to your backend in Angular I believe they are still using HttpRequest
and make sure to set withCredentials
to true.
https://angular.io/api/common/http/HttpRequest#withCredentials
My Angular application runs on the usual localhost:4200 and FusionAuth on localhost:9011. I can do login flow but when I try to call getUserInfo() from an Angular service, I am seeing a CORS error in Google Chrome console window.
You can read more about our CORS settings here but I am wondering if all you need is something like email then you can get that using the getUserInfoObservable
.
class AppComponent implements OnInit, OnDestroy {
private fusionAuthService: FusionAuthService = inject(FusionAuthService);
isLoggedIn: boolean = this.fusionAuthService.isLoggedIn();
userInfo: UserInfo | null = null;
isGettingUserInfo: boolean = false;
subscription?: Subscription;
ngOnInit(): void {
if (this.isLoggedIn) {
this.subscription = this.fusionAuthService
.getUserInfoObservable({
onBegin: () => (this.isGettingUserInfo = true),
onDone: () => (this.isGettingUserInfo = false),
})
.subscribe({
next: (userInfo) => (this.userInfo = userInfo),
error: (error) => console.error(error),
});
}
}
ngOnDestroy(): void {
this.subscription?.unsubscribe();
}
}
FusionAuth provides a feature called Identity Provider (IdP) Linking Strategies that allows you to link social login accounts to existing FusionAuth accounts. This feature is available since version 1.28.0.
There are several strategies you can use to link accounts:
Link On Email
: This strategy will create a new user if they don’t exist. However, if the user has an email address at their social provider which differs from the email address that was used to sign up for your application and which you imported to FusionAuth, then two accounts will be created.
Link On Username
: Similar to the Link On Email
strategy, this will also create a new user if they don’t exist. But it has a greater risk of account takeover and should be used with caution. In most cases, you would never want to enable more than one identity provider to link by username because there could be a username collision.
Pending
: This strategy will prompt the end user to sign into FusionAuth after they sign into the social provider, authoritatively linking the two accounts.
To implement this, you'd have to get the user to login via their social account and get their unique user Id. Then you'd take that user Id and create a link using the APIs. After the link is created, the next time the user went to login, they could use either their old email/password credentials or the linked social login.
Here's more information about IdP Linking Strategies.
Sources:
@justin-calareso to test this screen, you can always select preview on your theme to see if it would work if needed.
Then select the "Confirmation required" screen. Notice how I put "Alex did this" on this confirmation.
One of the easiest ways to try this out is to use Passwordless login. As you can see in the Theme I have the confirmation page example set which I added <h1>Confirmation page example</h1>
Now when I log in to the application I am presented with the option for "Login with magic link"
This will email me a link which I can open in a new private window (or different browser not already logged into the application).
Once I open this in the new window you will see that the confirmation required has my H1 tag showing "Confirmation page example".
I hope this helps.
@info-0 are you able to use our global one?
https://local.fusionauth.io/
will redirect to http://localhost:9011
If not a great option is to setup ngrok
https://fusionauth.io/docs/get-started/download-and-install/development/exposing-instance
ngrok http --request-header-add 'X-Forwarded-Port:443' 9011
@fusionauth-qhj5e I have brought this up internally, for now we are considering adding a PR to make it more clear for users.