Skip to content

Commit

Permalink
feat(services-bff): BFF (Backend for Frontend) (#15835)
Browse files Browse the repository at this point in the history
* Initial bootstrap for bff

* environment audit not optional

* Add infra file for admin-portal

* Auth login controller and service implemented

* Updates to auth and user modules and services

* Update project readme

* Add secret

* Remove unnecessary config

* Fix env config for ids

* Remove unused util isString

* chore: nx format:write update dirty files

* Rename dto to queries

* Add logout flow

* Finalize logout logic

* Remove proxy

* Move type from service to type file

* chore: nx format:write update dirty files

* Delete libs/auth/react/src/lib/bff/BFFProvider.tsx

* Delete libs/auth/react/src/lib/bff/BFFContext.tsx

* Small refactor in auth service

* Small refactor in test

* Small refactor

* Fix esbuild

* Add scope

* chore: nx format:write update dirty files

* Updates to bff service and client. WIP

* chore: nx format:write update dirty files

* Finishing proxy handling by the bff

* Add scope to token response for backwards compatibility

* Encrypted tokens, hooks update for admin portal, switch user, proxy updated

* feat(proxy-api): Support for proxy api, hooks update, regulations download connection with bff

* Better naming env

* Rename secrets in infra

* Refactor after self review

* Fix test and env cleanup

* Fix user menu test

* Updates to environment and config

* Update infra allowed external api urls to be hard coded

* Simplify client urls with bff postfix in it

* Add ingress to project and remove logout redirect path in favour of client base url

* Add docker express to services bff

* update config simpler syntax

* chore: nx format:write update dirty files

* Update config and redis dev setup

* Update crypto service to include algorithm in the encryption, explain better in comments what encrypt/decrypt is doing and update crypto test to not use mock

* Remove CORS entirely in favour of client proxy config

* Update error handling in bff backend, refactor infra and handle error query param in client

* When proxy service errors then handle as unauthorized. Update targetUrl to be defensive, i.e. no undefined possible.

* Remove unnecessary Uint8Array conversion

* Simplify the BFFUser object to not have dateOfBirth and remove double scope field which was due to backwards compatibility

* Update cookies to share constants, update options to be more secure

* access token expire time latency by 5 sec

* remove omit

* Update user profile cache ttl

* update cache ttl again and rename baseUrl to issuerUrl in ids service

* reaname var

* remove params from cache attempt that where not used in the callback

* Clean up old session in login callback if it exists

* Fix login callback cache clean up and revoke refresh token

* Update logout flow to clean up, revoke tokens and better validation. Also deletes the logout callback

* remove unused import

* Simplify error in favour of enhanced fetch

* created enhanced fetch module, moved pkce service to services, updated proxy service and a little refactor

* par support flag not optional

* Fix typo

* Add better validation to crypto decryption function

* Update validate uri to be more secure, create test for validate uri. Update port range in environment

* Remove state param from logout to ensure it will not be passed to redirect uri

* Adding more tests and increasing security in the function

* Refactor after reading comments from coderabbit

* remove private from method for test

* Move portal scopes to shareable location.

* Remove unused import

* Add no_refresh query to user endpoint in backend

* Polling and broadcaster added to react spa bff library

* Enhanced security in pkce service.and improve error handling to be more secure

* Update usePolling to have better types and secure resumabiltiy.

* Refactor useBroadcaster.

* Add client logic to handle the case if bff server goes down

* Fix tests and builds

* Fix portal infra local vars

* DX infra setup for services-bff

* Remove error log from revokeRefreshToken since it is handled by enhancedFetch and update download service local url

* Rename cached toke fields to be prefixed with encrypted and fix where encryption was missing. Also fix for revoking wrong token

* Better handling on errors in auth service

* Update api requests formatting and handling to handle exceptions and errors better.

* Update apps/services/bff/src/app/bff.config.ts

simpler redis config

Co-authored-by: Eiríkur Heiðar Nilsson <[email protected]>

* cleanup after commit from github

* Update after our pull request AI suggested the change

* Remove broadcaster mocks

* Remove redundant timeout in favour of poller

* Fix portal config, fix redis cache module init, update bff provider to handle logout in before redirect

* Remove timeout in logout broadcasting and throw the error in postRequest if not successful plain text response

* Revert the timeout in the logout

* chore: charts update dirty files

* Rename queries to dto for consistency in monorepo and add log for logout callback

* Fix cli error that got merged from main

* Fix prettier formatting error

* chore: nx format:write update dirty files

* fix storybook build

* ci: trigger from levy user

* fix: use portals-admin, added portal-env test

* Revert manual validation and use library

* Use fetch instead of post in download url

* Fix type errors and add forward get proxy api request

* fix: main conflict

* chore: charts update dirty files

* fix: prettier issues

* chore: prettify

* chore: nx format:write update dirty files

* ci: add services-bff to helm chart

* Fix env vars for feature deploy

* Fix health check to be excluded from prefix

* update global prefix logic

* update bff services options

* Remove bff redis name env var

* Update bff config again

* Update portal env spec for feature branch

* chore: charts update dirty files

* Update validation error log

* Remove database healthcheck

* Revert globalprefix options and update liveness and readiness infra checks

* chore: charts update dirty files

* Add auth controller tests

* Add logout log for testing in feature deploy

* remove unused

* clean up auth controller test

* chore: nx format:write update dirty files

* Add tests for proxy controller

* Add ref to infra for api

* update charts

* add zed editor config to gitignore

* Add support for mocks

* chore: nx format:write update dirty files

* Fix portal env spec

* chore: charts update dirty files

* Update mocking server logic for portals

* update mock logic

* fix: public envs (#16493)

* fix: merge conflict

* fix: improved zod schema generation

* test: update portal-env test for service building

* fix: generate feature deploy urls

* fix: improve getEnvUrl func

* feat: integrated bff to ServiceBuilder

* fix: more abstraction to dsl

* fix: simplify and cleanup

* chore: remove unused file

* chore: cleanup dupes

* chore: nx format:write update dirty files

* chore: more cleanup

---------

Co-authored-by: andes-it <[email protected]>

* chore: remove nx-command impl (#16532)

* chore: move nx runcommand cli to a new PR

* chore: commit save point

* chore: commit save point

* Update infra setup

* fix tests

* chore: charts update dirty files

* fix infra url

* Removed un used import

* fix: revert secret type changes

* chore: nx format:write update dirty files

* chore: cleanup

* fix feature deployment url

* fix tests

* fix missing logger

* chore: nx format:write update dirty files

* update api graphql bff config env var

* fix tests

* fix tests

* chore: charts update dirty files

* chore: nx format:write update dirty files

* grantnamespaces

* chore: charts update dirty files

* disable global auth on dev

* chore: charts update dirty files

* Update double negation query param

* feat: Better error message when running infra cli without aws credentials.

* Adding agent to proxy for for managing connections efficiently

* Enable PAR support

* update tests

* chore: charts update dirty files

---------

Co-authored-by: andes-it <[email protected]>
Co-authored-by: Eiríkur Heiðar Nilsson <[email protected]>
Co-authored-by: Jón Levy <[email protected]>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
5 people authored Oct 31, 2024
1 parent 7adc95a commit d0c9471
Show file tree
Hide file tree
Showing 149 changed files with 5,961 additions and 329 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ tmp/
out-tsc/
**/tsconfig.tsbuildinfo
infra/mountebank-imposter-config.json
mountebank-imposter-config.json
infra/helm/**/*.tgz

# dependencies
Expand Down Expand Up @@ -96,3 +97,4 @@ apps/**/index.html
.next

.nx/
.zed/
2 changes: 1 addition & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
/infra/helm/
/.nx/cache
/.nx/workspace-data
apps/web/public/assets/pdf.worker.min.mjs
apps/web/public/assets/pdf.worker.min.mjs
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"semi": false,
"trailingComma": "all",
"arrowParens": "always",
"plugins": ["./scripts/prettier-plugins/sort-projects"],
"plugins": ["./scripts/prettier-plugins/sort-projects.js"],
"endOfLine": "lf",
"overrides": [
{
Expand Down
45 changes: 23 additions & 22 deletions apps/api/infra/api.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,55 @@
import { json, ref, service, ServiceBuilder } from '../../../infra/src/dsl/dsl'
import {
AdrAndMachine,
AircraftRegistry,
Base,
ChargeFjsV2,
EnergyFunds,
Client,
CriminalRecord,
DirectorateOfImmigration,
Disability,
DistrictCommissionersLicenses,
DistrictCommissionersPCard,
DrivingLicense,
DrivingLicenseBook,
Education,
EnergyFunds,
Finance,
Firearm,
FishingLicense,
Frigg,
HealthDirectorateOrganDonation,
HealthDirectorateVaccination,
HealthInsurance,
HousingBenefitCalculator,
Hunting,
IcelandicGovernmentInstitutionVacancies,
Inna,
IntellectualProperties,
JudicialAdministration,
JudicialSystemServicePortal,
Labor,
MunicipalitiesFinancialAid,
NationalRegistry,
NationalRegistryB2C,
OccupationalLicenses,
OfficialJournalOfIceland,
OfficialJournalOfIcelandApplication,
Passports,
Payment,
PaymentSchedule,
Properties,
RskCompanyInfo,
TransportAuthority,
Vehicles,
VehiclesMileage,
VehicleServiceFjsV1,
WorkMachines,
IcelandicGovernmentInstitutionVacancies,
RskProcuring,
AircraftRegistry,
HousingBenefitCalculator,
OccupationalLicenses,
ShipRegistry,
DistrictCommissionersPCard,
DistrictCommissionersLicenses,
DirectorateOfImmigration,
Hunting,
SignatureCollection,
SocialInsuranceAdministration,
IntellectualProperties,
Inna,
TransportAuthority,
UniversityCareers,
OfficialJournalOfIceland,
OfficialJournalOfIcelandApplication,
JudicialSystemServicePortal,
Frigg,
HealthDirectorateOrganDonation,
HealthDirectorateVaccination,
Vehicles,
VehicleServiceFjsV1,
VehiclesMileage,
WorkMachines,
} from '../../../infra/src/dsl/xroad'

export const serviceSetup = (services: {
Expand Down Expand Up @@ -469,5 +469,6 @@ export const serviceSetup = (services: {
'api-catalogue',
'application-system',
'consultation-portal',
'services-bff-portals-admin',
)
}
2 changes: 2 additions & 0 deletions apps/api/src/app/environments/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ const prodConfig = () => ({
basePath: process.env.ISLYKILL_SERVICE_BASEPATH,
},
})

const devConfig = () => ({
production: false,
xroad: {
Expand Down Expand Up @@ -207,6 +208,7 @@ const devConfig = () => ({
basePath: process.env.ISLYKILL_SERVICE_BASEPATH,
},
})

export const getConfig =
process.env.PROD_MODE === 'true' || process.env.NODE_ENV === 'production'
? prodConfig()
Expand Down
24 changes: 21 additions & 3 deletions apps/portals/admin/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
"executor": "@nx/webpack:dev-server",
"options": {
"buildTarget": "portals-admin:build",
"hmr": true
"hmr": true,
"proxyConfig": "apps/portals/admin/proxy.config.json"
},
"configurations": {
"production": {
Expand Down Expand Up @@ -92,11 +93,28 @@
"parallel": false
}
},
"start-bff": {
"executor": "nx:run-commands",
"options": {
"commands": [
"node -r esbuild-register src/cli/cli.ts run-local-env services-bff-portals-admin"
],
"cwd": "infra"
}
},
"dev": {
"executor": "nx:run-commands",
"options": {
"commands": ["yarn start portals-admin"],
"parallel": true
"commands": [
"yarn nx run portals-admin:start-bff",
"yarn start portals-admin"
]
}
},
"mockmode": {
"executor": "nx:run-commands",
"options": {
"commands": ["API_MOCKS=true yarn start portals-admin"]
}
},
"docker-static": {
Expand Down
6 changes: 6 additions & 0 deletions apps/portals/admin/proxy.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"/stjornbord/bff/*": {
"target": "http://localhost:3010",
"secure": false
}
}
28 changes: 21 additions & 7 deletions apps/portals/admin/src/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
import { ApolloProvider } from '@apollo/client'
import { AuthProvider } from '@island.is/auth/react'
import { LocaleProvider } from '@island.is/localization'
import { defaultLanguage } from '@island.is/shared/constants'
import {
ApplicationErrorBoundary,
PortalRouter,
isMockMode,
} from '@island.is/portals/core'
import { BffProvider, createMockedInitialState } from '@island.is/react-spa/bff'
import { FeatureFlagProvider } from '@island.is/react/feature-flags'
import { ApplicationErrorBoundary, PortalRouter } from '@island.is/portals/core'
import { modules } from '../lib/modules'
import { client } from '../graphql'
import { defaultLanguage } from '@island.is/shared/constants'
import environment from '../environments/environment'
import { client } from '../graphql'
import { modules } from '../lib/modules'
import { AdminPortalPaths } from '../lib/paths'
import { createRoutes } from '../lib/routes'
import { adminPortalScopes } from '@island.is/auth/scopes'

const mockedInitialState = isMockMode
? createMockedInitialState({
scopes: adminPortalScopes,
})
: undefined

export const App = () => (
<ApolloProvider client={client}>
<LocaleProvider locale={defaultLanguage} messages={{}}>
<ApplicationErrorBoundary>
<AuthProvider basePath={AdminPortalPaths.Base}>
<BffProvider
applicationBasePath={AdminPortalPaths.Base}
mockedInitialState={mockedInitialState}
>
<FeatureFlagProvider sdkKey={environment.featureFlagSdkKey}>
<PortalRouter
modules={modules}
Expand All @@ -26,7 +40,7 @@ export const App = () => (
}}
/>
</FeatureFlagProvider>
</AuthProvider>
</BffProvider>
</ApplicationErrorBoundary>
</LocaleProvider>
</ApolloProvider>
Expand Down
47 changes: 0 additions & 47 deletions apps/portals/admin/src/auth.ts

This file was deleted.

12 changes: 3 additions & 9 deletions apps/portals/admin/src/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,10 @@ import {
import { onError } from '@apollo/client/link/error'
import { RetryLink } from '@apollo/client/link/retry'

import { authLink } from '@island.is/auth/react'

const uri =
process.env.NODE_ENV === 'development'
? 'http://localhost:4444/api/graphql'
: '/api/graphql'

const httpLink = new HttpLink({
uri: ({ operationName }) => `${uri}?op=${operationName}`,
uri: ({ operationName }) => `/stjornbord/bff/api/graphql?op=${operationName}`,
fetch,
credentials: 'include',
})

const retryLink = new RetryLink()
Expand All @@ -34,7 +28,7 @@ const errorLink = onError(({ graphQLErrors, networkError }) => {
})

export const client = new ApolloClient({
link: ApolloLink.from([retryLink, errorLink, authLink, httpLink]),
link: ApolloLink.from([retryLink, errorLink, httpLink]),
cache: new InMemoryCache({
typePolicies: {
UserProfile: {
Expand Down
4 changes: 2 additions & 2 deletions apps/portals/admin/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import '@island.is/api/mocks'

import { userMonitoring } from '@island.is/user-monitoring'
import React, { StrictMode } from 'react'
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'

import { isRunningOnEnvironment } from '@island.is/shared/utils'

import './auth'
import environment from './environments/environment'
import { App } from './app/App'

Expand Down
2 changes: 1 addition & 1 deletion apps/portals/my-pages/src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export const Header = ({ position }: Props) => {
/>
)}

{user && <UserLanguageSwitcher user={user} />}
{user && <UserLanguageSwitcher />}

<Box className={styles.overview} marginRight={[1, 1, 2]}>
<Button
Expand Down
18 changes: 18 additions & 0 deletions apps/services/bff/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
39 changes: 39 additions & 0 deletions apps/services/bff/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# BFF (Backend for Frontend)

## About

The BFF (Backend for Frontend) service serves as an intermediary layer for multiple clients, such as the admin portal, service portal, and other applications. It is designed to centralize authentication and business logic, ensuring a secure and streamlined communication process between clients and backend resources.

This service handles user authentication through our IdentityServer, facilitating secure access and session management. Once authenticated, the BFF proxies and manages requests to our GraphQL API, ensuring only authorized requests are processed.

## Getting Started

To set up and run the BFF service, use the following commands:

### Start Development Server

`yarn start services-bff`
Starts the service on `localhost:3010`.

### Build for Production

`yarn nx build services-bff`
Builds the service to `dist/apps/services/bff`.
For production: `nx build services-bff --configuration=production`

### Lint Code

`yarn nx lint services-bff`

### Run Tests

`yarn nx test services-bff`
Runs tests with Jest and outputs coverage to `coverage/apps/services/bff`.

### Starts Redis server with Docker

`yarn nx dev-services services-bff`

## Code owners and maintainers

- [Aranja](https://github.com/orgs/island-is/teams/aranja/members)
Loading

0 comments on commit d0c9471

Please sign in to comment.