Skip to content

Commit

Permalink
FIX: Vite envs not being injected (#218)
Browse files Browse the repository at this point in the history
* fix bug where variables arent injected correctly

* .

* satisfy lint

* .

* changed dockerfile

* ignore scripts

* lint

* fix
  • Loading branch information
ssb-jnk authored Apr 9, 2024
1 parent 4b170ee commit e3173c1
Show file tree
Hide file tree
Showing 10 changed files with 859 additions and 4,182 deletions.
4 changes: 4 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
DAPLA_TEAM_API_URL=
DAPLA_CTRL_ADMIN_GROUPS=
DAPLA_CTRL_DOCUMENTATION_URL=
DAPLA_CTRL_DAPLA_START_URL=
11 changes: 5 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ RUN npm ci && npm run build

FROM node:20-alpine

COPY --from=builder /usr/local/app/dist /usr/local/app/dist
WORKDIR /usr/local/app

COPY package*.json .
COPY server.js .
COPY --from=builder /usr/local/app/dist ./dist
COPY package*.json server.js ./

RUN npm i --save-exact express vite-express
RUN npm install --ignore-scripts --save-exact express vite-express

ENV PORT 8080
ENV PORT=8080
EXPOSE 8080

CMD ["npm", "run", "prod"]
ENTRYPOINT ["sh", "-c", "./dist/vite-envs.sh && npm run prod"]
4,890 changes: 719 additions & 4,171 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"prepare": "npx vite-envs update-types",
"dev": "nodemon server.js -w server.js",
"prod": "NODE_ENV=production node server.js",
"build": "tsc && vite build",
Expand Down Expand Up @@ -46,6 +47,7 @@
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"typescript": "^5.4.4",
"vite-envs": "^4.0.6",
"vite": "^5.2.8"
}
}
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import SharedBucketDetail from './pages/SharedBucketDetail/SharedBucketDetail.ts
import { Routes, Route } from 'react-router-dom'

const App = () => {
console.log(import.meta.env)

return (
<Routes>
<Route element={<ProtectedRoute />}>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const Header = () => {
<div className={styles.navigation}>
<div className={styles.links}>
<Link
href='https://statistics-norway.atlassian.net/wiki/spaces/DAPLA/pages/3803611153/Dapla+Ctrl'
href={import.meta.env.DAPLA_CTRL_DOCUMENTATION_URL ?? ''}
isExternal={true}
icon={<BookOpen size='20' />}
>
Expand Down
5 changes: 3 additions & 2 deletions src/pages/TeamOverview/TeamOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,9 @@ const TeamOverview = () => {
title='Teamoversikt'
content={renderContent()}
button={
// TODO: URL should be an environment variable set using vite envs or fetch from server.js as an api call
<Button onClick={() => window.open('https://start.dapla.ssb.no', '_blank')}>+ Opprett team</Button>
<Button onClick={() => window.open(import.meta.env.DAPLA_CTRL_DAPLA_START_URL ?? '', 'noopener')}>
+ Opprett team
</Button>
}
/>
)
Expand Down
60 changes: 60 additions & 0 deletions src/utils/services.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { DAPLA_TEAM_API_URL, flattenEmbedded } from '../utils/utils'

// eslint-disable-next-line
export const fetchAPIData = async (url: string): Promise<any> => {
const response = await fetch(url)
Expand Down Expand Up @@ -26,6 +28,64 @@ export const fetchUserInformationFromAuthToken = async (): Promise<TokenData> =>
return { ...jwt } as TokenData
}

interface Group {
uniform_name: string
users: {
principal_name: string
}[]
}

const GROUPS_URL = `${DAPLA_TEAM_API_URL}/groups`

const fetchGroupMembership = async (groupUniformName: string): Promise<Group> => {
const groupsUrl = new URL(`${GROUPS_URL}/${groupUniformName}/users`, window.location.origin)
const embeds = ['users']
const selects = ['uniform_name', 'users.principal_name']

groupsUrl.searchParams.set('embed', embeds.join(','))
groupsUrl.searchParams.append('select', selects.join(','))

try {
const groupDetail = await fetchAPIData(groupsUrl.toString())

return flattenEmbedded(groupDetail)
} catch (error) {
if (error instanceof ApiError) {
console.error('Failed to fetch group membership:', error)
throw error
} else {
const apiError = new ApiError(500, 'An unexpected error occurred')
console.error('Failed to fetch group membership:', apiError)
throw apiError
}
}
}

export const isDaplaAdmin = async (userPrincipalName: string): Promise<boolean> => {
const adminGroups = import.meta.env.DAPLA_CTRL_ADMIN_GROUPS ?? ''
const daplaAdminGroupsSeperated = adminGroups.split(',')
if (daplaAdminGroupsSeperated.length === 0) return false

try {
const adminGroupUsers = await Promise.all(
daplaAdminGroupsSeperated.map((groupUniformName) => fetchGroupMembership(groupUniformName))
)

return adminGroupUsers.some(
(group) =>
group.users && group.users.length > 0 && group.users.some((user) => user.principal_name === userPrincipalName)
)
} catch (error) {
if (error instanceof ApiError) {
console.error('Failed to fetch dapla admins:', error)
throw error
} else {
const apiError = new ApiError(500, 'An unexpected error occurred')
console.error('Failed to fetch dapla admins:', apiError)
throw apiError
}
}
}
export class ApiError extends Error {
public code: number

Expand Down
38 changes: 37 additions & 1 deletion src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,37 @@
/// <reference types="vite/client" />
/// <reference types="vite-envs/client" />

type ImportMetaEnv = {
// Auto-generated by `npx vite-envs update-types` and hot-reloaded by the `vite-env` plugin
BASE_URL: string
MODE: string
DEV: boolean
PROD: boolean
BUILD_TIME: number
VERSION: string
DAPLA_TEAM_API_URL: string
DAPLA_CTRL_ADMIN_GROUPS: string
DAPLA_CTRL_DOCUMENTATION_URL: string
DAPLA_CTRL_DAPLA_START_URL: string
// @user-defined-start
/*
* Here you can define your own special variables
* that would be available on `import.meta.env` but
* that vite-envs does not know about.
* This section will be preserved thanks to the special comments.
* Example:
*/
SSR: boolean
// @user-defined-end
}

interface ImportMeta {
// Auto-generated by `npx vite-envs update-types`

url: string

readonly hot?: import('vite-envs/types/hot').ViteHotContext

readonly env: ImportMetaEnv

glob: import('vite-envs/types/importGlob').ImportGlobFunction
}
27 changes: 26 additions & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,32 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import { viteEnvs } from 'vite-envs'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
plugins: [
react(),
viteEnvs({
declarationFile: '.env',
computedEnv: async ({ resolvedConfig }) => {
const path = await import('path')
const fs = await import('fs/promises')

const packageJson = JSON.parse(await fs.readFile(path.join(resolvedConfig.root, 'package.json'), 'utf-8'))

/*
* Here you can define any arbitrary value they will be available
* in `import.meta.env` and it's type definitions.
* You can also compute defaults for variable declared in `.env` files.
*/
return {
BUILD_TIME: Date.now(),
VERSION: packageJson.version,
}
},
}),
],
build: {
sourcemap: true,
},
})

0 comments on commit e3173c1

Please sign in to comment.