Compare commits

..

No commits in common. "master" and "develop" have entirely different histories.

7 changed files with 95 additions and 31 deletions

View File

@ -85,10 +85,7 @@ steps:
- apk add --no-cache git yq - apk add --no-cache git yq
- git config --global user.name "woodpecker-bot" - git config --global user.name "woodpecker-bot"
- git config --global user.email "ci@dvirlabs.com" - git config --global user.email "ci@dvirlabs.com"
- | - git clone "https://$${GIT_USERNAME}:$${GIT_TOKEN}@git.dvirlabs.com/dvirlabs/my-apps.git"
if [ ! -d "my-apps" ]; then
git clone "https://${GIT_USERNAME}:${GIT_TOKEN}@git.dvirlabs.com/dvirlabs/my-apps.git"
fi
- cd my-apps - cd my-apps
- | - |
TAG="${CI_COMMIT_BRANCH}-${CI_COMMIT_SHA:0:7}" TAG="${CI_COMMIT_BRANCH}-${CI_COMMIT_SHA:0:7}"
@ -97,22 +94,3 @@ steps:
git add manifests/${CI_REPO_NAME}/values.yaml git add manifests/${CI_REPO_NAME}/values.yaml
git commit -m "backend: update tag to $TAG" || echo "No changes" git commit -m "backend: update tag to $TAG" || echo "No changes"
git push origin HEAD git push origin HEAD
trigger-gitops-via-push:
name: Trigger apps-gitops via Git push
image: alpine/git
environment:
GIT_USERNAME:
from_secret: GIT_USERNAME
GIT_TOKEN:
from_secret: GIT_TOKEN
commands: |
git config --global user.name "woodpecker-bot"
git config --global user.email "ci@dvirlabs.com"
git clone "https://$${GIT_USERNAME}:$${GIT_TOKEN}@git.dvirlabs.com/dvirlabs/apps-gitops.git"
cd apps-gitops
echo "# trigger at $(date) by $${CI_REPO_NAME}" >> .trigger
git add .trigger
git commit -m "ci: trigger apps-gitops build" || echo "no changes"
git push origin HEAD

View File

@ -1,7 +1,6 @@
from fastapi import FastAPI, APIRouter from fastapi import FastAPI, APIRouter
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
import uvicorn
import os import os
from dotenv import load_dotenv from dotenv import load_dotenv
import yaml import yaml
@ -151,4 +150,5 @@ app.include_router(router, prefix="/api")
# ✅ This is the missing part: # ✅ This is the missing part:
if __name__ == "__main__": if __name__ == "__main__":
import uvicorn
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True) uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)

View File

@ -27,3 +27,4 @@ RUN dos2unix /docker-entrypoint.d/10-generate-env.sh && chmod +x /docker-entrypo
EXPOSE 80 EXPOSE 80
CMD ["nginx", "-g", "daemon off;"] CMD ["nginx", "-g", "daemon off;"]

View File

@ -8,6 +8,8 @@
"name": "frontend", "name": "frontend",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@react-keycloak/web": "^3.4.0",
"keycloak-js": "^26.2.0",
"react": "^19.1.0", "react": "^19.1.0",
"react-beautiful-dnd": "^13.1.1", "react-beautiful-dnd": "^13.1.1",
"react-dom": "^19.1.0", "react-dom": "^19.1.0",
@ -962,6 +964,46 @@
"@jridgewell/sourcemap-codec": "^1.4.14" "@jridgewell/sourcemap-codec": "^1.4.14"
} }
}, },
"node_modules/@react-keycloak/core": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@react-keycloak/core/-/core-3.2.0.tgz",
"integrity": "sha512-1yzU7gQzs+6E1v6hGqxy0Q+kpMHg9sEcke2yxZR29WoU8KNE8E50xS6UbI8N7rWsgyYw8r9W1cUPCOF48MYjzw==",
"dependencies": {
"react-fast-compare": "^3.2.0"
},
"funding": {
"type": "patreon",
"url": "https://www.patreon.com/reactkeycloak"
},
"peerDependencies": {
"react": ">=16"
}
},
"node_modules/@react-keycloak/web": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@react-keycloak/web/-/web-3.4.0.tgz",
"integrity": "sha512-yKKSCyqBtn7dt+VckYOW1IM5NW999pPkxDZOXqJ6dfXPXstYhOQCkTZqh8l7UL14PkpsoaHDh7hSJH8whah01g==",
"dependencies": {
"@babel/runtime": "^7.9.0",
"@react-keycloak/core": "^3.2.0",
"hoist-non-react-statics": "^3.3.2"
},
"funding": {
"type": "patreon",
"url": "https://www.patreon.com/reactkeycloak"
},
"peerDependencies": {
"keycloak-js": ">=9.0.2",
"react": ">=16.8",
"react-dom": ">=16.8",
"typescript": ">=3.8"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/@rolldown/pluginutils": { "node_modules/@rolldown/pluginutils": {
"version": "1.0.0-beta.9", "version": "1.0.0-beta.9",
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.9.tgz", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.9.tgz",
@ -2080,6 +2122,11 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/keycloak-js": {
"version": "26.2.0",
"resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-26.2.0.tgz",
"integrity": "sha512-CrFcXTN+d6J0V/1v3Zpioys6qHNWE6yUzVVIsCUAmFn9H14GZ0vuYod+lt+SSpMgWGPuneDZBSGBAeLBFuqjsw=="
},
"node_modules/keyv": { "node_modules/keyv": {
"version": "4.5.4", "version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@ -2403,6 +2450,11 @@
"react": "^19.1.0" "react": "^19.1.0"
} }
}, },
"node_modules/react-fast-compare": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
},
"node_modules/react-icons": { "node_modules/react-icons": {
"version": "5.5.0", "version": "5.5.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",

View File

@ -10,6 +10,8 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@react-keycloak/web": "^3.4.0",
"keycloak-js": "^26.2.0",
"react": "^19.1.0", "react": "^19.1.0",
"react-beautiful-dnd": "^13.1.1", "react-beautiful-dnd": "^13.1.1",
"react-dom": "^19.1.0", "react-dom": "^19.1.0",

9
frontend/src/keycloak.js Normal file
View File

@ -0,0 +1,9 @@
import Keycloak from 'keycloak-js';
const keycloak = new Keycloak({
url: 'https://keycloak.dvirlabs.com/',
realm: 'lab', // ⬅️ Change to your realm name
clientId: 'navix', // ⬅️ Change to your client ID in Keycloak
});
export default keycloak;

View File

@ -1,10 +1,32 @@
import { StrictMode } from 'react' import { StrictMode, useState, useEffect } from 'react';
import { createRoot } from 'react-dom/client' import { createRoot } from 'react-dom/client';
import './index.css' import './index.css';
import App from './App.jsx' import App from './App.jsx';
import keycloak from './keycloak';
function SecuredApp() {
const [authenticated, setAuthenticated] = useState(false);
useEffect(() => {
keycloak.init({ onLoad: 'login-required' }).then((auth) => {
if (!auth) {
window.location.reload();
} else {
setAuthenticated(true);
}
});
// Optional: refresh token
setInterval(() => {
keycloak.updateToken(70).catch(() => keycloak.logout());
}, 6000);
}, []);
return authenticated ? <App /> : <div>Loading...</div>;
}
createRoot(document.getElementById('root')).render( createRoot(document.getElementById('root')).render(
<StrictMode> <StrictMode>
<App /> <SecuredApp />
</StrictMode>, </StrictMode>
) );