Skip to content

Conversation

BlairCurrey
Copy link
Contributor

@BlairCurrey BlairCurrey commented Jan 14, 2025

Changes proposed in this pull request

  • updates frontend to use api credentials (tenant id, api secret) to make request to admin api and handles 401 errors on bad/missing credentials

Context

fixes #3108

Checklist

  • Related issues linked using fixes #number
  • Tests added/updated
  • Make sure that all checks pass
  • Bruno collection updated (if necessary)
  • Documentation issue created with user-docs label (if necessary)
  • OpenAPI specs updated (if necessary)

- not removing yet because not sure if we might end up using it.
could be useful if we want to make global redirect if this is not set.
…ll apollo requests

Uses the assets and list asset query.
This POC passes the request to the listAsset function.
Which imports the apolloClient directly and passes
the cookie from request headers in the context.
To avoid having to set this on each query as we compose
it, my intention is to create a new getApolloClient
function and use that insteadof directly importing a
single client. This enables us to form a link to handle setting the headers per request (as opposed to static
links that are used across all requests as it is currently).
- enables authLink to get tenantId, apiSecret from cookie in request
- wondered if this was a performance concern
(maybe why we had single instance before?) but found
several things indicating this is OK and even recommended:
    - apollographql/apollo-client#9520 (comment)
    - https://www.apollographql.com/blog/how-to-use-apollo-client-with-remix
- see TODOs in apollo client in frontend.
maybe need to remove some env vars and
verify how no tenantid/secret are handled
@github-actions github-actions bot added pkg: backend Changes in the backend package. pkg: frontend Changes in the frontend package. type: source Changes business logic type: localenv Local playground pkg: mock-ase labels Jan 14, 2025
@BlairCurrey BlairCurrey changed the title feature(fronted): implement admin api credentials feat(fronted): implement admin api credentials Jan 15, 2025
@BlairCurrey BlairCurrey changed the title feat(fronted): implement admin api credentials feat(fronted): tenanted admin api credentials Jan 15, 2025
Comment on lines 99 to 102
'flex p-2 font-medium rounded-md',
!hasApiCredentials &&
name !== 'Home' &&
'text-gray-400 pointer-events-none cursor-not-allowed'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disables nav links (Assets, Wallet Addresses, etc.) in nav menu when api credentials arent set. This keeps user on page w/ the form to submit the credentials and avoids an inevitable error (which you can see if manually forming the url).

Copy link
Contributor Author

@BlairCurrey BlairCurrey Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if there is more visual feedback we can give on the disabled state im all ears. With these changes it looks the same, they just arent clickable. See the pic here showing it.

Normally I'd make it a lighter gray but lighter gray already represents non-active tabs (and dont have any room to go lighter contrast wise). Perhaps make the text black on all of them (active or not) but keep the dark background to represent active. Then make the disabled links light gray?

Strikethrough, italics, etc. all seemd kinda meh too and a different color doesnt really seem to communicate disabled... could completely hide them but felt like showing what content there is still made more sense.

image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me the api credentials form is similar to a login form, so I believe hiding the contents from the sidebar is clearer for the user that he cannot navigate anywhere until they add their credentials.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree w @oana-lolea, probably more straightforward to just hide everything until we are "logged in"

Copy link
Contributor Author

@BlairCurrey BlairCurrey Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to hide if credentials not set, thanks for the feedback.


if (!global.__apolloClient) {
global.__apolloClient = new ApolloClient({
export async function getApolloClient(request: Request) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before this change, we re-used 1 server side apollo client for all requests.

This is no longer tenable because we need to support the concept of different requestors. Hence, a getApolloClient that is formed for each request with the correct apiSecret and tenantId.

I did wonder if this was a weird, not performant thing to do but actually I found it is preferred to avoid side effects between clients (someone else's credentials, cache issues, etc.). Some supporting evidence for this:

Comment on lines -63 to -70
defaultOptions: {
query: {
fetchPolicy: 'no-cache'
},
mutate: {
fetchPolicy: 'no-cache'
}
}
Copy link
Contributor Author

@BlairCurrey BlairCurrey Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no longer needed since clients arent shared between requests and we arent worried about accidentally sharing cache

original reasoning here: #969 (comment)

httpOnly: true,
path: '/',
sameSite: 'lax',
secure: process.env.NODE_ENV === 'production',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mkurapov Is there anything to test here? I recall some shenanigans with the snackbar message cookie and some scenario. Mobile perhaps? Didn't notice any actual problems in testing.

Comment on lines +209 to +211
errorMessage = error.message.includes('401')
? 'Unauthorized. Please set your API credentials.'
: error.message
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On 401 (missing or bad credentials), shows our error page with this message and prompt to return to homepage where credentials can be set.
image

@BlairCurrey BlairCurrey marked this pull request as ready for review January 15, 2025 20:00
Comment on lines 170 to 171
SIGNATURE_VERSION: 1
SIGNATURE_SECRET: iyIgCprjb9uL8wFckR+pLEkJWMB7FJhgkvqhTQR/964=
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about having this still here (so we don't have to enter them in the local playground)?
If we want to use another tenant, we can just clear the credentials on the home screen

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that appropriate logic to have in the production image?

I was worried about having that functionality when using multiple tenants. For a single tenant it's good - it just works the way it always has. But if you have multiple tenants and set this then everyone is that tenant. That made it seem potentially risky to have so removing it was defensive. But thinking from the other side, it does streamline things not only in local development but for the single-tenant use-case which may be the most common one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about it another way, these env vars are required. So all existing deployments have them set.

If an existing deployment adds a new tenant, now how do we know which signature to use? How do we know not to use this one? I think the signature is just no longer a decision we can make at deployment.

Copy link
Contributor Author

@BlairCurrey BlairCurrey Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Im not against streamlining the localenv more. Currently it just logs the credentials and you copy-paste them. I did think a bit about alternatives.

I think its probably possible to simply trigger the action from the MASE with the env vars we are using there. The session with credentials are set in a remix action function which runs on the remix server at POST / (or could move to a dedicated /api/set-credentials. So I think in theory we could expose the port in docker and add a fetch call in the MASE to set them on startup. It does seem like a more appropriate thing to do from our development fixture than the frontend app itself.

Copy link
Contributor

@mkurapov mkurapov Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So all existing deployments have them set.

The SIGNATURE_SECRET and SIGNATURE_VERSION are optional in frontend I believe

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that makes sense in terms of the developer environment. Doesn't have to be in this PR.

Im giving it a shot... may not be too hard.

Copy link
Contributor Author

@BlairCurrey BlairCurrey Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking more about allowing them to set SIGNATURE_SECRET and then using that if we can, otherwise requiring one from the session. I think the question is how do we know if the session one is required or if we can use the env var? I think maybe it's just if there is only 1 tenant in the backend or not?

I think we'd need an extra api call before making the gql request, and it may be difficult to use the gql api for it since we are assuming all requests will have the tenant details, and thats what we're trying to figure out.

export const loader = async ({ request }: LoaderFunctionArgs) => {
   // ...
   
  const shouldUseSessionSecret = await checkApiIfMultitenanted() // boolean

  const assets = await listAssets(request, shouldUseSessionSecret, {
    ...pagination.data
  })
  
  // ... 
}

I guess this saves some intermittent input from operator (ie when there is no cookie with session) but how important is that? Dont really like this. And we cannot just always use the ENV var if set because new tenants would just use them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah shoot... setting from the MASE doesn't work because its a cookie... the browser wont have it.

Copy link
Contributor Author

@BlairCurrey BlairCurrey Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the MASE to log a link which will prefill the form. So you can click the link and press save. This is something integrators could leverage as well when distributing credentials out of band.

In theory I think we should be able to automatically submit it in a useEffect hook but I wasn't able to get that working.

Copy link
Contributor Author

@BlairCurrey BlairCurrey Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nvm, got the auto submit working. MASE logs a link like http://localhost:3010/?tenantId=438fa74a-fa7d-4317-9ced-dde32ece1787&apiSecret=iyIgCprjb9uL8wFckR%2BpLEkJWMB7FJhgkvqhTQR%2F964%3D which you can use to set without any additional input.

Perhaps when an operator creates a new tenant we can form this sort of link for them to pass along to the tenant out of band.

Comment on lines 99 to 102
'flex p-2 font-medium rounded-md',
!hasApiCredentials &&
name !== 'Home' &&
'text-gray-400 pointer-events-none cursor-not-allowed'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree w @oana-lolea, probably more straightforward to just hide everything until we are "logged in"

@github-actions github-actions bot removed pkg: backend Changes in the backend package. type: source Changes business logic labels Jan 17, 2025
- removes the action from the index. the intention is to
expose the remix server port over docker and  call this
from the MASE to set the api credentials on start
requires changing intent to be set as an input. submitting form bypasses the button so the action didnt have the intent  and
failed when auto submitting.
@mkurapov
Copy link
Contributor

Screen.Recording.2025-01-20.at.13.43.51.mov

Getting odd behaviour where 401 on the request is happening when navigating to the same page in succession

@BlairCurrey
Copy link
Contributor Author

Screen.Recording.2025-01-20.at.13.43.51.mov
Getting odd behaviour where 401 on the request is happening when navigating to the same page in succession

Im seeing this on main too. Would you mind verifying you see the same? Looks like its an existing bug to me.

@mkurapov
Copy link
Contributor

@BlairCurrey yep, seeing on main as well. Looking into it

@mkurapov
Copy link
Contributor

@BlairCurrey Ah, I think I got it. If you do it within one second of clicking, it looks like the signature validation fails because of the canApiSignatureBeProcessed replay attack protection in backend

@BlairCurrey BlairCurrey requested a review from mkurapov January 21, 2025 16:12
@mkurapov mkurapov linked an issue Jan 21, 2025 that may be closed by this pull request
3 tasks

if (!global.__seeded) {
const tenantId = process.env.OPERATOR_TENANT_ID
const apiSecret = process.env.SIGNATURE_SECRET
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't seem like SIGNATURE_SECRET is set in the environment anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was removed from the frontend - is that what you're referring to? The docker compose sets them for the mock ase. When I spin up rafiki it doesnt error on the lines below for the secret, and it spits out a link with the apiSecret.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, got it. My mistake.

@BlairCurrey BlairCurrey merged commit 1bb2a9b into 2893/multi-tenancy-v1 Jan 24, 2025
31 of 37 checks passed
@BlairCurrey BlairCurrey deleted the bc/3108/tenanted-admin-ui-requests branch January 24, 2025 18:23
njlie added a commit that referenced this pull request Jul 6, 2025
* feat(backend): tenants table v1 (#3132)

* feat(auth): tenants table v1 (#3133)

* feat(auth): tenants table v1

* fix: add updatedAt, createdAt

* feat: add deletedAt

* feat(auth): tenant service (#3144)

* feat(auth): tenant service

* chore(auth): format

* fix(auth): jest test warning about migration

* fix(auth): remove temporary code

* feat(auth): soft delete tenants

* fix(auth): return erroneously removed tests

* feat(backend): tenants service (#3123) (#3140)

* feat(backend): tenant service

* fix: integration tests

* feat: use soft delete

* refactor: compare whole object in test

* fix: better gql errors in tests

* feat: add idp columns to tenant model

* feat: pagination tests, push deletedAt to auth api call

* feat: add cache

* fix: update localenv environment variables

* feat: make some tenants fields optional, small refactors

* feat(auth, backend): seed operator tenant (#3156)

* feat(auth): migration to seed operator tenant

* feat(backend): migration to seed operator tenant

* chore(localenv): add env vars for operator tenant

* test(backend): set operator env variables in jest config

* test(auth): set operator env variables in jest config

* test(auth, backend): load env vars into jest environment script

* feat(auth,backend): update migrations with error messages

* test(integration): adding operator tenant vars

* chore(backend, localenv): replace OPERATOR_TENANT_SECRET with existing API_SECRET

* feat(integration): sign Admin API requests during integration tests (#3177)

* fix(backend): await signature verification

* test(integration): add signatures to apollo client requests

* test(backend): sign GraphQL requests in test environment

* Revert "test(backend): sign GraphQL requests in test environment"

This reverts commit 0a128d1.

* chore(backend): remove sig verification in test files

* feat(backend): tenant signature validation for admin api (#3164)

* feat(auth): tenants table v1

* feat(backend): tenant service

* feat: use soft delete

* feat: add idp columns to tenant model

* feat: pagination tests, push deletedAt to auth api call

* feat: add cache

* feat(backend): tenant signature validation for admin api

* fix: rebase errors

* fix: remove admin api secret check from app

* fix: always expect tenant id in request

* chore: remove some logs

* feat: await signature verification, test improvements

* fix: better util parameters

* fix: add tenant info to apollo context

* feat: fix integration tests

* fix: make tenant required on extended apollo context

* feat: auth service-to-service api (#3148)

* feat(auth): add service api with /healtz endpoint

* feat(auth): tenant routes

* feat(auth): service api error handling

* chore(auth): rm old todo

* fix(auth): how errors are set

* fix(auth): improve tenant tests, cleanup tenant get response,

* feat(backend): auth service api client

* fix(auth): change status codes to 204 where no body

* fix(backend): format

* feat(auth): add required deletedAt to DELETE /tenant body

* feat(backend): AUTH_SERVICE_API_URL env var

* fix(backend): auth service client tests to mock codes correctly

* feat(backend): add AuthServiceClient dep

* feat(backend): use auth service client in tenant service

* chore(auth): format

* chore(auth): format

* fix(integration,localenv): auth service api config

* fix(backend,auth): update tenant api to support deletedAt

* docs: update with env vars

* fix(backend): dep container type

* fix(localenv): docker compose config

* fix(backend): add default header to api client

* feat(backend): tenanted assets (#3206)

* feat(backend): migration to backfill tenantId on assets

* feat(backend): add tenantId to asset, use it in service

* feat(backend): use tenantId in asset resolvers

* test(backend): update tests to use asset tenantId where necessary

* test(backend): truncate tenant table manually in tenant tests

* test(backend): update failing accounting tests

* test(backend): update tenant service test

* test: fix accounting tests linting

* test(backend): update accounting tests

* feat(backend): use tenantId when fetching asset

* test(backend): make tests work with separate middleware

* test(backend): keep operator tenant when truncating tables

* test(backend): skip tenant pagination tests for now

* test(backend): seed operator tenant in truncateTable

* test(backend): seed operator tenant after tenants service is done

* test(backend): use separate schema for tenant tests

* test(backend): pass operator tenant id in pagination tests

* feat(backend): make tenantId required in asset pagination

* test(backend): update tenant service tests

* chore(backend): update config file

* test: update truncateTables to take in dbSchema

* feat(backend): make tenantId optional in asset pagination

* feat(fronted): tenanted admin api credentials (#3213)

* feat(frontend): set api credentials on session

* chore(frontend): more details in todo comment

* refactor(frontend): move credentials form from modal to component on index

* chore(frontend): mark dialog for removal

- not removing yet because not sure if we might end up using it.
could be useful if we want to make global redirect if this is not set.

* feat(frontend): store api creds in server side session

* feat(frontend): POC for adding tenantId from session to headers for all apollo requests

Uses the assets and list asset query.
This POC passes the request to the listAsset function.
Which imports the apolloClient directly and passes
the cookie from request headers in the context.
To avoid having to set this on each query as we compose
it, my intention is to create a new getApolloClient
function and use that insteadof directly importing a
single client. This enables us to form a link to handle setting the headers per request (as opposed to static
links that are used across all requests as it is currently).

* feat(frontend): form apollo client per request

- enables authLink to get tenantId, apiSecret from cookie in request
- wondered if this was a performance concern
(maybe why we had single instance before?) but found
several things indicating this is OK and even recommended:
    - apollographql/apollo-client#9520 (comment)
    - https://www.apollographql.com/blog/how-to-use-apollo-client-with-remix

* fix(mock-ase): update seed script to pass tenant sig/id verifcation

* feat(frontend): block api cred form submit on invalid uuid

* feat(frontend): handle errors, WIP apollo client

- see TODOs in apollo client in frontend.
maybe need to remove some env vars and
verify how no tenantid/secret are handled

* feat(frontend): disable nav links

* docs(localenv): update readme to not say kratos is required

* chore(frontend): format

* chore(frontend): rm unused component

* chore(frontend): rm commented out code

* chore(frontend): formatting

* refactor(frontend): better error parsing

* chore(frontend): rm todo

* refactor(frontend): use session api for deletion, not manual

* fix(frontend): display error based on message

reverses previous commit to use apollo error. proved unreliable

* fix(frontend): rm SIGNATURE_SECRET, SIGNATURE_VERSION env vars

* feat(mock-ase): log operator/tenant details to streamline use of frontend

* feat(frontend): dont show nav items if api creds required and not set

* feat(frontend): move api credential set action to own endpoint

- removes the action from the index. the intention is to
expose the remix server port over docker and  call this
from the MASE to set the api credentials on start

* feat(frontend): prefill api credential form

* chore(frontend): format

* feat(frontend): auto submit form if values passed in

requires changing intent to be set as an input. submitting form bypasses the button so the action didnt have the intent  and
failed when auto submitting.

* fix: reinstate sig version env var

* feat(backend): tenant support for wallet address (#3114) (#3152)

* feat(backend): tenant service

* fix: integration tests

* feat: use soft delete

* refactor: compare whole object in test

* fix: better gql errors in tests

* feat: add idp columns to tenant model

* feat: pagination tests, push deletedAt to auth api call

* feat: add cache

* fix: update localenv environment variables

* feat(3114): add tenant to wallet address.

* feat(3114): test fixes.

* feat: make some tenants fields optional, small refactors

* feat(auth): tenants table v1

* feat(backend): tenant service

* feat: use soft delete

* feat: add idp columns to tenant model

* feat: pagination tests, push deletedAt to auth api call

* feat: add cache

* feat(backend): tenant signature validation for admin api

* fix: rebase errors

* feat(3114): update seed.ts

* fix: remove admin api secret check from app

* fix: always expect tenant id in request

* chore: remove some logs

* feat(3114): update for auth and resource server.

* feat(3114): fix asset service.test.ts

* feat(3114): fix tests.

* feat(3114): merged with latest tenant changes.

* feat(3114): extract tenant id from tenant context instead of admin input variable.

* feat(3114): test case updates, obtain tenant from header.

* feat(3114): fix test cases for wallet address.

* feat(3114): address review comments.

* feat(3114): rework tenantId to not be mandatory for wallet address service layer.

* feat(3114): rework tenantId to not be mandatory for wallet address service layer.

* feat(3114): rework tenantId to not be mandatory for wallet address service layer.

* feat(3114): fix tenant service test case.

* feat(3114): fix tenant service test case.

* feat(3114): fix tenant service test case.

* feat(3114): fix tenant service test case.

* feat(3114): fix tenant service test case.

* feat(3114): force 'forTenantId'.

* feat(3114): force 'forTenantId'.

* feat(3114): force 'forTenantId'.

* feat(3114): enhancements for 'forTenantId'.

* feat(3114): test case fixes.

* feat(3114): internal server error

* feat(3114): test case.

* feat(3114): test case.

* feat(3114): review feedback.

* feat(3114): review feedback.

* feat(3114): remove tenant on quote.

* feat(3114): default operator tenant.

* feat(3114): review feedback.

* feat(3114): review feedback from Max.

* feat(3114): review feedback from Max.

* feat(3114): fixed.

* feat(3114): review feedback.

* feat(3114): review feedback.

* feat(3114): review feedback. do not force error on graphql middleware.

* feat(3114): fix the integration test.

* feat(3114): further review comments.

* feat(3114): further review comments.

* feat(3114): final round with Max.

* feat(3114): revert.

* feat(3114): remove unused.

* feat(3114): set the correct operator id.

---------

Co-authored-by: Nathan Lie <[email protected]>

* feat(backend): backend tenant graphql resolvers (#3234)

* feat: backend tenant graphql resolvers

* chore: formatting

* fix: extra testing db for tenants

* feat: bruno collection

* feat: update graphql schema comments

* fix: review comments

* feat: optional idp secret & consent url

* feat: tenant response requirement

* feat: make delete operator-only

* chore: cleanup

* chore(integration): fix apollo client constructor

* chore(integration): fix & tidy integration tests

* chore(backend): update auth apollo client signature timestamp

* docs(localenv): add details for tenant credentials for admin ui (#3251)

* docs(localenv): add details for tenant credentials for admin ui

* doc(localenv): fix typo

* chore: admin ui requirement info and add example output

* chore: use full name for MASE, instead of acronym

* feat(auth): tenanted grants (#3187)

* feat(auth): tenanted grants

* fix: tests

* feat: update bruno collection

* fix: tests

* feat: update bruno requests, fix integration tests

* feat: handle tenants with no idp info

* feat: backfill tenants on grants, trim down queries

* feat: use tenantId in grant revocation

* fix: service function signatures

* feat(2915): admin front-end for tenant support (#3254)

* feat: backend tenant graphql resolvers

* chore: formatting

* fix: extra testing db for tenants

* feat: bruno collection

* feat: update graphql schema comments

* fix: review comments

* feat: optional idp secret & consent url

* feat: tenant response requirement

* feat: make delete operator-only

* feat(2915): admin front-end for tenant support

* feat(2915): apply permissions for tenant screens

* feat(2915): improvements

* chore: cleanup

* feat(2915): merged with tenant branch. updates to update screen.

* feat(2915): update fixes.

* feat(3180): bug fixes and testing with non operator tenant.

* feat(3180): bug fixes and testing with non operator tenant.

* feat(2915): review feedback

* feat(2915): fix update. field validation for email.

* feat(2915): formatting.

* feat(2915): fix.

* feat(2915): review fixes.

---------

Co-authored-by: Nathan Lie <[email protected]>

* feat(backend/frontend): 3256 able to view deleted tenant (#3299)

* feat(3256): able to view deleted tenant

* feat(3256): fix backend tests.

* feat(3256): allow for switching between deleted and not.

* feat(3256): review comments.

* feat(backend): tenanted incoming payments (#3271)

* Draft version of tenanted incoming payments

* Finished fixing unit and integration tests

* PR comments fixes

* Created helper function that adds tenantId to incoming payment id

* Removed tenantId from url in bruno requests, added tenantId in url of the incoming payment, fixed tests accordingly

* Fixed formatting

* Replaced get with findOne when querying using id and tenantId.

* feat(backend): tenanted quotes and outgoing payments (#3171)

* feat: tenanted quotes - first iteration with dummy tenant

* feat: tenanted quotes - replace hardcoded tenantId values with creation of tenant

* feat: tenanted quotes - formatting

* feat: tenanted quotes - fix outgoing payments service test

* WIP

* Fix tests - TODOs not resolved yet

* feat: tenanted quotes and outgoing payments - update resolvers and fix all tests

* feat: tenanted quotes and outgoing payments - remove unnecessary comments

* feat: tenanted quotes and outgoing payments - fix integration tests

* feat: tenanted quotes and outgoing payments - fix vulnerabilities scan

* feat: tenanted quotes and outgoing payments - partially fix vulnerabilities scan

* feat: tenanted quotes and outgoing payments - fix get routes for quotes and outgoing payments

* feat: tenanted quotes and outgoing payments - fix outgoing payments routes unit tests

* chore: fix docker image scans (#3272)

* chore: fix path-to-regexp lib

* chore: update base node image version in Dockerfiles

---------

Co-authored-by: bsanduc <[email protected]>

* feat: tenanted quotes and outgoing payments - remove tenantId from ILP payment method handler

* feat: tenanted quotes and outgoing payments - remove tenantId from StartQuoteOptions in quote service

* feat: tenanted quotes and outgoing payments - fix unit tests

* feat: tenanted quotes and outgoing payments - remove tenantId from GraphQL Input types

* feat: tenanted quotes and outgoing payments - format

* feat: tenanted quotes and outgoing payments - remove tenantId from integration test inputs

* feat: tenanted quotes and outgoing payments - remove unnecessary tenantId

* feat: tenanted quotes and outgoing payments - update Bruno collection

* feat: tenanted quotes and outgoing payments - address PR comments

* feat: tenanted quotes and outgoing payments - fix Bruno collection merge conflict

* feat: tenanted quotes and outgoing payments - add tenantId to outgoing payments routes, add test cases for unknown tenantId

* feat: tenanted quotes and outgoing payments - update comments for GraphQL types

* feat: tenanted quotes and outgoing payments - update quote resolver context

* feat: tenanted quotes and outgoing payments - add tenantId to outgoing payment and quote routes middleware

* feat: tenanted quotes and outgoing payments - add test for getting outgoing payments WA middleware

* feat: tenanted quotes and outgoing payments - modify get outgoing payment query in service

* feat: tenanted quotes and outgoing payments - add test for getting WA from quote middleware

* feat: tenanted quotes and outgoing payments - remove unused import

* feat: tenanted quotes and outgoing payments - remove unused import

* feat: tenanted quotes and outgoing payments - format

---------

Co-authored-by: Max Kurapov <[email protected]>

* feat(frontend): add operator-contextual dropdowns for tenant selection (#3289)

* feat(frontend): add operator-contextual dropdowns for tenant selection during asset, wallet address, and peer creation

* feat: improved dropdown labels

* fix: use tenantId properly during asset creation

* chore: gql type, remove dangling log

* chore: regenerate graphql

* feat(tenantSettings): initial implementation (#3281)

* fix(tenant): duplicate test

* feat(tenants): settings

* feat(tenants): add default settings when creating tenant

* feat(tenantSettings): tests updates

* chore(tenantSettings): format

* chore(tenantSettings): format

* tests(tenantSettings): mock call to auth when creating tenant

* tests(tenants): when tenant is created, default settings should be set

* feat(graphql): tenant settings

* fix(tenantSettings): address PR comments

* feat: handle updating operator api secret (#3328)

* feat(frontend): disallow api secret update and change tenant form to submit sections independently

* feat(backend): disallow tenant api secret update in admin api

* feat(backend): add service method to update secret, call on app start

* chore: rm log

* fix(fronted): 'no any' lint error

* fix(backend): error on failed secret update from config

* fix(backend): wallet address resolver tests to be operator/non-operator as needed

- previous way of controlling if the request was from an operator
or not no longer worked after changing
app start to sync apiSecret

* test(backend): update tenant tests to reflect operator cant update apiSecret

* chore: fix format

* chore: debug ci test failure (working locally)

* chore: fix format

* chore: debug ci test failure (working locally)

* chore: debug ci test failure (working locally)

* chore: debug ci test failure (working locally)

* chore: debug ci test failure (working locally)

* chore: debug ci test failure (working locally)

* chore: debug ci test failure (working locally)

* chore: debug ci test failure (working locally)

* chore: debug ci test failure (working locally)

* chore: debug ci test failure (working locally)

* chore: debug ci test failure (working locally)

* fix: test side effects

* fix(backend): uncomment test

* Update packages/backend/src/tenants/service.ts

Co-authored-by: Max Kurapov <[email protected]>

* fix(backend): rm unushesd nock

* feat(backend): set cache on update operator secret method

* fix(frontend): typo

* fix: typo

---------

Co-authored-by: Max Kurapov <[email protected]>

* feat: tenanted peers (#3352)

* feat: Added tenantId to peers

* Added tenantId to getPage, updated contexts

* Removed unused imports + updated some tests

* Changes following PR comments

* Fixes on resolvers: create and get peer, deposit liquidity and create peer liquidity withdrawal

* Added missing tests for create and get peer

* feat(backend)!: tenanted rates endpoints (#3327)

* feat: tenanted rates endpoints - first iteration, WIP

* feat: tenanted rates endpoints - format

* feat: tenanted rates endpoints - deprecate exchange rates url env var, WIP

* feat: tenanted rates endpoints - use operator tenant id for telemetry, internal rates service

* feat: tenanted rates endpoints - don't throw if exchange urls is not found

* feat: tenanted rates endpoints - more fixes, WIP

* feat: tenanted rates endpoints - fix integration tests

* feat: tenanted rates endpoints - format

* Add optional operator exchange rates URL as env var

* Check if exchange rates URL is set when creating assets

* Address comments

* Address more comments

* Format

* Add tenantId to ConnectorAccount

* Revert pnpm lock file

* Restore package.json

* Revert "Format"

This reverts commit 219baa9.

* feat(wallet-address)!: possibility to specify wallet address range (#3325)

* feat(graphql): schema update for specifying settings when creating tenant

* feat(tenant): add possibility to specify initial tenant settings as an operator

* test(tenant): create with settings

* feat(wallet-address): rename url to address

* fix(tenant-settings): duplicate key for tenant

* feat(wallet-address): replace url field with address field

url field was replaced with address field, because now with range in wallet address, it is possible
for the caller, to specify just the portion of the wallet address url. There is no need to specify
the whole url in order to create wallet address.

#3278

* chore(backend): format

* fix(tests): some of them

* fix(frontend): due to wallet address url change

* fix(mase): due to wallet address url change

* fix(backend): tests due to wallet address url change

* test(integration): fix tests and have default address for operator

* fix(wallet-address): test for operator can perform cross tenant create@

* test(tenant-settings): remove pagination tests for tenant settings

* docs(bruno): rename of the walletaddress url variable

* test(wallet-address): create with tenant settings or not as an operator or not

* feat(wallet-address): put creation of it into new function

* chore(format): everything

* feat(tenant-settings): add tests for upsert

* feat(tenant-settings): add more tests and remove pagination

* Update packages/backend/src/open_payments/wallet_address/service.ts

Co-authored-by: Max Kurapov <[email protected]>

* Update packages/backend/src/graphql/resolvers/tenant_settings.ts

Co-authored-by: Max Kurapov <[email protected]>

* Update packages/backend/src/graphql/schema.graphql

Co-authored-by: Max Kurapov <[email protected]>

* chore(graphql): generate schema

* fix(tenant): mapping settings to tenant

* chore(graphql): generate schema

---------

Co-authored-by: Max Kurapov <[email protected]>

* feat(backend): tenanted webhooks (#3317)

* tests(tenants): when tenant is created, default settings should be set

* feat(graphql): tenant settings

* fix(tenantSettings): address PR comments

* fix(tenantSettings): address PR comments

* feat(backend): tenanted webhooks

* fix: rebase

* chore: fix some rebasing issues

* feat: use resource tenant ids where available

* feat: add tenant id to tests; temporary operator tenant id in peer webhook events

* fix: build errors

* feat: remove temporary tenantId code from before tenanted peers

* fix: build errors

* feat: update settings formatting, handle NaN

* fix: tests

* feat: key mapping as const, non-optional settings for webhook event function

* fix: prevent tests from failing with default settings

---------

Co-authored-by: golobitch <[email protected]>

* fix: post-main merge test fixes

* feat(backend): also publish webhooks to operators if primary recipient is tenant (#3368)

* tests(tenants): when tenant is created, default settings should be set

* feat(graphql): tenant settings

* fix(tenantSettings): address PR comments

* fix(tenantSettings): address PR comments

* feat(backend): tenanted webhooks

* fix: rebase

* chore: fix some rebasing issues

* feat: add tenant id to tests; temporary operator tenant id in peer webhook events

* fix: build errors

* feat: remove temporary tenantId code from before tenanted peers

* fix: build errors

* tests(tenants): when tenant is created, default settings should be set

* fix(tenantSettings): address PR comments

* feat(backend): tenanted webhooks

* chore: fix some rebasing issues

* feat(backend): also publish webhooks to operators if primary recipient is tenant

* fix: rebase issues

* fix: tests

* feat: add webhook model

* refactor: move webhook & webhookevent models

* feat: include tenant id in webhook gql response

* fix: generated files

* fix: rebase errors

* feat: review comments

* feat: remove getWebhook, rename processWebhookEvent to processWebhook

* fix: remove operatorSettings from sendWebhook

---------

Co-authored-by: golobitch <[email protected]>

* fix(localenv): use https in openPaymentsUrl env vars in local backend config (#3417)

* feat(backend): try to match 'wallet address not found' webhook to tenant by prefix (#3426)

* feat(backend): try to match 'wallet address not found' webhook to tenant by prefix

* fix: negative test for prefix matching

* fix: tests and withConfigOverride usage

* fix: bruno collection for open payments examples (#3421)

* fix: bruno collection for open payments examples

* fix: bruno graphql resolvers

* fix: add tenant id to loadWalletAddressIdsIntoVariables for bruno collection

* feat(backend): validate tenant settings inputs (#3435)

* feat(backend): validate tenant settings inputs

* fix: resolver tests

* feat: use error model for tenant setting resolvers

* feat: allow 0 for certain settings

* feat(backend): make tenantId required when fetching peer by destination address (#3452)

* test(backend): update payment method tests after minSendAmount feature merge

* feat(localenv): add tenanted mock ASE to local environment (#3451)

* feat(localenv): add tenanted mock ASE to local environment

* fix: build issues

* fix: integration tests

* feat: use correct tenant credentials in mock ASE log output

* feat: add tenantId filter to list assets query

* feat: seed tenant with webhook url

* feat: tenanted OP example bruno collection; idp config in ase seed

* feat(backend): allow tenant id to be specified during tenant creation (#3457)

* feat(backend): allow tenant id to be specified during tenant creation

* feat: validate uuid input

* fix: tests & gql generation

* fix: build issues

* feat(backend): abstract away payment method generation, add ILP_ADDRESS tenantSetting (#3460)

* feat: add ILP_ADDRESS tenant setting, generate default one using tenant id

* chore: decouple incomingPayment from streamCredentialGeneration

* chore: generate StreamServer every time we get getStreamCredentials

* feat(backend): allowing passing in ilpAddress when generating stream credentials

* feat: adding paymentMethodProviderService

* feat: use paymentMethodProviderService in receiverService

* feat: use paymentMethodProviderService in incomingPayment service & model

* feat: use updated receiver structure to resolve ilp payment destination in ilpPaymentMethodService

* feat: use updated receiver structure in outgoingPaymentService

* chore: add paymentMethodProviderService to app init

* chore: update test files to use paymentMethodProviderService

* chore: lint

* test: use paymentMethodProviderService.getPaymentMethods during outgoingPayment creation

* chore(localenv): add ilpAddress for non-operator tenant for happy-life

* feat: update connector, peer service to determine & parse destination addresses

* fix: use correct redirect for tenanted mock-idp

* test(backend): adding test for longest prefix match for peer

* test(backend): add tests for stream-address middleware

* feat(backend): only set streamDestination & streamServer defined if valid tenantIlpAddress found

* chore(backend): remove unused part of account middleware

* chore(backend): add types to middleware

* test(backend): update stream-address middleware test

* test(backend): test fixes

---------

Co-authored-by: Nathan Lie <[email protected]>

* feat(localenv): tenanted mock ase webhook server apollo client (#3459)

* feat: remove tenant id from continuation uri (#3470)

* fix(tests): fix performance tests for multi-tenancy (#3475)

* feat(backend): add tenantId to webhook, outgoing + combined payments pagination resolvers (#3474)

* feat(backend): add tenantId to webhook pagination resolver

* feat(backend): add tenantId to outgoing payments pagination resolver

* feat(backend): add tenantId to combined payments pagination resolver

* feat(backend): add migration to add tenantId to combinedPaymentsView

* chore: updated generated graphql types

* test(backend): fix tests

* feat(localenv): refer to admin UI url as belonging to operator or tenant correctly

* chore(bruno): fix grant request outgoing payment in Open Payments example

* chore(bruno): fix grant request outgoing payment in Tenanted Open Payments example

* feat(backend): add sendAllWebhooksToOperator env variable (#3503)

* feat(backend): add sendAllWebhooksToOperator env variable

* test(backend): update webhook service test

* chore(backend): rename sendTenantWebhooksToOperator env var

* test(backend): remove tests which are now encapsulated by finalizeWebhookRecipients tests

* chore(backend): send wallet address not found webhook to operator

when no matching wallet address prefix for tenant

* test(backend): remove wallet address tests which are now encapsulated by finalizeWebhookRecipients tests

* chore(backend): linting

* test(backend): make actionable incoming payment test less flaky

---------

Co-authored-by: Max Kurapov <[email protected]>
Co-authored-by: Blair Currey <[email protected]>
Co-authored-by: Jason Bruwer <[email protected]>
Co-authored-by: oana-lolea <[email protected]>
Co-authored-by: sanducb <[email protected]>
Co-authored-by: Tadej Golobic <[email protected]>
Co-authored-by: golobitch <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg: frontend Changes in the frontend package. pkg: mock-ase type: localenv Local playground

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Multi-Tenant] Tenanted Admin UI Requests

4 participants