Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package digger-cli for openSUSE:Factory checked in at 2025-11-02 22:33:29 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/digger-cli (Old) and /work/SRC/openSUSE:Factory/.digger-cli.new.1980 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "digger-cli" Sun Nov 2 22:33:29 2025 rev:39 rq:1315055 version:0.6.131 Changes: -------- --- /work/SRC/openSUSE:Factory/digger-cli/digger-cli.changes 2025-10-29 21:08:09.910429911 +0100 +++ /work/SRC/openSUSE:Factory/.digger-cli.new.1980/digger-cli.changes 2025-11-02 22:33:44.329605146 +0100 @@ -1,0 +2,13 @@ +Sun Nov 02 06:46:14 UTC 2025 - Johannes Kastl <[email protected]> + +- Update to version 0.6.131: + * fix: fix terragrunt non-interactive flag (#2332) + * Revert "Move drift reconciliation to CE (#2346)" (#2357) + * Move drift reconciliation to CE (#2346) + * token service ui functionality (#2356) + * Fix/breardon2011/UI arch lock (#2355) + * Fix/breardon2011/UI arch lock (#2354) + * adjust arch lock (#2353) + * address type errors, bump charts (#2352) + +------------------------------------------------------------------- Old: ---- digger-cli-0.6.130.obscpio New: ---- digger-cli-0.6.131.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ digger-cli.spec ++++++ --- /var/tmp/diff_new_pack.2iNMUE/_old 2025-11-02 22:33:45.481653438 +0100 +++ /var/tmp/diff_new_pack.2iNMUE/_new 2025-11-02 22:33:45.481653438 +0100 @@ -19,7 +19,7 @@ %define executable_name digger Name: digger-cli -Version: 0.6.130 +Version: 0.6.131 Release: 0 Summary: CLI for the digger open source IaC orchestration tool License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.2iNMUE/_old 2025-11-02 22:33:45.525655282 +0100 +++ /var/tmp/diff_new_pack.2iNMUE/_new 2025-11-02 22:33:45.529655450 +0100 @@ -6,7 +6,7 @@ <param name="exclude">go.mod</param> <param name="exclude">go.work</param> <param name="exclude">go.work.sum</param> - <param name="revision">v0.6.130</param> + <param name="revision">v0.6.131</param> <param name="match-tag">v*</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.2iNMUE/_old 2025-11-02 22:33:45.553656456 +0100 +++ /var/tmp/diff_new_pack.2iNMUE/_new 2025-11-02 22:33:45.557656623 +0100 @@ -1,7 +1,7 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/diggerhq/digger</param> - <param name="changesrevision">49717065b51bd76dd7568d19f2c3cfb214973cdc</param></service><service name="tar_scm"> + <param name="changesrevision">e271ff07c354d40a3405c008883f7313e44c3bee</param></service><service name="tar_scm"> <param name="url">https://github.com/johanneskastl/digger</param> <param name="changesrevision">8fe377068e53e2050ff4c745388d8428d2b13bb0</param></service></servicedata> (No newline at EOF) ++++++ digger-cli-0.6.130.obscpio -> digger-cli-0.6.131.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/Dockerfile_ui new/digger-cli-0.6.131/Dockerfile_ui --- old/digger-cli-0.6.130/Dockerfile_ui 2025-10-28 20:58:52.000000000 +0100 +++ new/digger-cli-0.6.131/Dockerfile_ui 2025-10-29 16:27:04.000000000 +0100 @@ -7,15 +7,14 @@ COPY ui/package.json ./ # Install dependencies first -# Explicitly tell npm to install for linux/amd64 platform (for cloud deployment) -# This ensures correct optional dependencies like @rollup/rollup-linux-x64-musl -RUN npm install --cpu=x64 --os=linux --libc=musl && \ +# npm will automatically install correct platform-specific binaries (amd64 or arm64) +RUN npm install && \ npm cache clean --force # Copy source code (node_modules excluded via .dockerignore) COPY ui/ ./ -# Build the application for linux/amd64 (with node adapter) +# Build the application (with node adapter) RUN npm run build # Production stage @@ -26,8 +25,9 @@ # Copy package file COPY ui/package.json ./ -# Install production dependencies only for linux/amd64 -RUN npm install --omit=dev --cpu=x64 --os=linux --libc=musl && \ +# Install production dependencies only +# npm will automatically install correct platform-specific binaries (amd64 or arm64) +RUN npm install --omit=dev && \ npm cache clean --force # Copy built application and server entry from builder diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/action.yml new/digger-cli-0.6.131/action.yml --- old/digger-cli-0.6.130/action.yml 2025-10-28 20:58:52.000000000 +0100 +++ new/digger-cli-0.6.131/action.yml 2025-10-29 16:27:04.000000000 +0100 @@ -236,11 +236,11 @@ description: "Pre-compiled version of digger CLI to install. Must correspond to a valid release tag (vX.Y.Z). This value overrides the version derived from the github.action_ref." required: false default: "" - digger-os: + digger-os: description: "OS variant of the digger CLI to install. Valid configurable values are: windows, linux, darwin, freebsd." required: false default: "Linux" - digger-arch: + digger-arch: description: "Architecture of the digger CLI to install. Valid configurable values are: amd64, arm64, 386." required: false default: "X64" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/helm-charts/opentaco/values.yaml new/digger-cli-0.6.131/helm-charts/opentaco/values.yaml --- old/digger-cli-0.6.130/helm-charts/opentaco/values.yaml 2025-10-28 20:58:52.000000000 +0100 +++ new/digger-cli-0.6.131/helm-charts/opentaco/values.yaml 2025-10-29 16:27:04.000000000 +0100 @@ -260,7 +260,7 @@ ui: image: repository: taco-ui - tag: "latest" + tag: "v0.1.0" replicaCount: 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/helm-charts/taco-ui/Chart.yaml new/digger-cli-0.6.131/helm-charts/taco-ui/Chart.yaml --- old/digger-cli-0.6.130/helm-charts/taco-ui/Chart.yaml 2025-10-28 20:58:52.000000000 +0100 +++ new/digger-cli-0.6.131/helm-charts/taco-ui/Chart.yaml 2025-10-29 16:27:04.000000000 +0100 @@ -2,7 +2,7 @@ name: taco-ui description: Taco UI - Web-based frontend for OpenTaco infrastructure management platform type: application -version: 0.1.0 -appVersion: "v0.1.0" +version: 0.1.1 +appVersion: "v0.1.1" icon: https://raw.githubusercontent.com/diggerhq/digger/main/docs/logo/digger-logo.png diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/libs/execution/terragrunt.go new/digger-cli-0.6.131/libs/execution/terragrunt.go --- old/digger-cli-0.6.130/libs/execution/terragrunt.go 2025-10-28 20:58:52.000000000 +0100 +++ new/digger-cli-0.6.131/libs/execution/terragrunt.go 2025-10-29 16:27:04.000000000 +0100 @@ -26,7 +26,6 @@ func (terragrunt Terragrunt) Apply(params []string, plan *string, envs map[string]string) (string, string, error) { params = append(params, []string{"-lock-timeout=3m"}...) params = append(params, "--auto-approve") - params = append(params, "--terragrunt-non-interactive") if plan != nil { params = append(params, *plan) } @@ -40,7 +39,6 @@ func (terragrunt Terragrunt) Destroy(params []string, envs map[string]string) (string, string, error) { params = append(params, "--auto-approve") - params = append(params, "--terragrunt-non-interactive") stdout, stderr, exitCode, err := terragrunt.runTerragruntCommand("destroy", true, envs, nil, params...) if exitCode != 0 { logCommandFail(exitCode, err) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/taco/.gitignore new/digger-cli-0.6.131/taco/.gitignore --- old/digger-cli-0.6.130/taco/.gitignore 2025-10-28 20:58:52.000000000 +0100 +++ new/digger-cli-0.6.131/taco/.gitignore 2025-10-29 16:27:04.000000000 +0100 @@ -1,3 +1,4 @@ /taco /statesman -/terraform-provider-opentaco \ No newline at end of file +/terraform-provider-opentaco +/token_service diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/taco/Dockerfile_statesman new/digger-cli-0.6.131/taco/Dockerfile_statesman --- old/digger-cli-0.6.130/taco/Dockerfile_statesman 2025-10-28 20:58:52.000000000 +0100 +++ new/digger-cli-0.6.131/taco/Dockerfile_statesman 2025-10-29 16:27:04.000000000 +0100 @@ -27,9 +27,9 @@ ARG COMMIT_SHA WORKDIR /app -# Install ca-certificates, curl for HTTPS requests +# Install ca-certificates, curl, jq for HTTPS requests and URL encoding RUN apt-get update && \ - apt-get install -y ca-certificates curl && \ + apt-get install -y ca-certificates curl jq && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/taco/Dockerfile_token_service new/digger-cli-0.6.131/taco/Dockerfile_token_service --- old/digger-cli-0.6.130/taco/Dockerfile_token_service 2025-10-28 20:58:52.000000000 +0100 +++ new/digger-cli-0.6.131/taco/Dockerfile_token_service 2025-10-29 16:27:04.000000000 +0100 @@ -10,11 +10,12 @@ COPY internal/ ./internal/ # Download dependencies and build +# Note: CGO is required for SQLite support RUN cd cmd/token_service && \ go mod tidy && \ - CGO_ENABLED=0 GOOS=linux go build \ + CGO_ENABLED=1 GOOS=linux go build \ -ldflags="-X 'main.Version=${COMMIT_SHA}' -s -w" \ - -a -installsuffix cgo \ + -a \ -o token_service . # Multi-stage build - use a minimal image for runtime diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/taco/Makefile new/digger-cli-0.6.131/taco/Makefile --- old/digger-cli-0.6.130/taco/Makefile 2025-10-28 20:58:52.000000000 +0100 +++ new/digger-cli-0.6.131/taco/Makefile 2025-10-29 16:27:04.000000000 +0100 @@ -160,6 +160,13 @@ @echo "\nš SQLite..." && atlas migrate diff $(NAME) --env sqlite @echo "\nā All migrations generated successfully!" +atlas-apply-sqlite: + @echo "Applying SQLite migrations..."; \ + SQLITE_PATH="$${OPENTACO_SQLITE_DB_PATH:-/app/data/taco.db}"; \ + mkdir -p "$$(dirname "$$SQLITE_PATH")"; \ + DB_URL="sqlite://$$SQLITE_PATH"; \ + atlas migrate apply --url "$$DB_URL" --dir "file://migrations/sqlite" + # Validate and lint all migrations atlas-lint-all: ## Validate and lint all migration files diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/taco/scripts/entrypoint.sh new/digger-cli-0.6.131/taco/scripts/entrypoint.sh --- old/digger-cli-0.6.130/taco/scripts/entrypoint.sh 2025-10-28 20:58:52.000000000 +0100 +++ new/digger-cli-0.6.131/taco/scripts/entrypoint.sh 2025-10-29 16:27:04.000000000 +0100 @@ -16,7 +16,9 @@ case $BACKEND in postgres) echo "Applying PostgreSQL migrations..." - DB_URL="postgres://${OPENTACO_POSTGRES_USER}:${OPENTACO_POSTGRES_PASSWORD}@${OPENTACO_POSTGRES_HOST}:${OPENTACO_POSTGRES_PORT}/${OPENTACO_POSTGRES_DATABASE}?sslmode=${OPENTACO_POSTGRES_SSLMODE:-disable}" + # URL-encode the password to handle special characters + ENCODED_PASSWORD=$(printf '%s' "$OPENTACO_POSTGRES_PASSWORD" | jq -sRr @uri) + DB_URL="postgres://${OPENTACO_POSTGRES_USER}:${ENCODED_PASSWORD}@${OPENTACO_POSTGRES_HOST}:${OPENTACO_POSTGRES_PORT}/${OPENTACO_POSTGRES_DATABASE}?sslmode=${OPENTACO_POSTGRES_SSLMODE:-disable}" atlas migrate apply --url "$DB_URL" --dir "file:///app/migrations/postgres" ;; mysql) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/ui/src/api/tokens.ts new/digger-cli-0.6.131/ui/src/api/tokens.ts --- old/digger-cli-0.6.130/ui/src/api/tokens.ts 1970-01-01 01:00:00.000000000 +0100 +++ new/digger-cli-0.6.131/ui/src/api/tokens.ts 2025-10-29 16:27:04.000000000 +0100 @@ -0,0 +1,67 @@ + +export const getTokens = async (organizationId: string, userId: string) => { + const query = new URLSearchParams({ org_id: organizationId, user_id: userId }); + const url = `${process.env.TOKENS_SERVICE_BACKEND_URL}/api/v1/tokens?${query.toString()}`; + const response = await fetch(url, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }) + if (!response.ok) { + throw new Error(`Failed to get tokens: ${response.statusText}`); + } + return response.json(); +} + +export const createToken = async (organizationId: string, userId: string, name: string, expiresAt: string | null ) => { + const response = await fetch(`${process.env.TOKENS_SERVICE_BACKEND_URL}/api/v1/tokens`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + org_id: organizationId, + user_id: userId, + name: name, + expires_in: expiresAt, + }), + }) + if (!response.ok) { + throw new Error(`Failed to create token: ${response.statusText}`); + } + return response.json(); +} + +export const verifyToken = async (token: string) => { + const response = await fetch(`${process.env.TOKENS_SERVICE_BACKEND_URL}/api/v1/tokens/verify`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + token: token, + }), + }) + if (!response.ok) { + throw new Error(`Failed to verify token: ${response.statusText}`); + } + return response.json(); +} + +export const deleteToken = async (organizationId: string, userId: string, tokenId: string) => { + const response = await fetch(`${process.env.TOKENS_SERVICE_BACKEND_URL}/api/v1/tokens/${tokenId}`, { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + org_id: organizationId, + user_id: userId, + }), + }) + if (!response.ok) { + throw new Error(`Failed to delete token: ${response.statusText}`); + } + return response.json(); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/ui/src/api/tokens_serverFunctions.ts new/digger-cli-0.6.131/ui/src/api/tokens_serverFunctions.ts --- old/digger-cli-0.6.130/ui/src/api/tokens_serverFunctions.ts 1970-01-01 01:00:00.000000000 +0100 +++ new/digger-cli-0.6.131/ui/src/api/tokens_serverFunctions.ts 2025-10-29 16:27:04.000000000 +0100 @@ -0,0 +1,28 @@ +import { createServerFn } from "@tanstack/react-start"; +import { createToken, getTokens } from "./tokens"; +import { verifyToken } from "./tokens"; +import { deleteToken } from "./tokens"; + +export const getTokensFn = createServerFn({method: 'GET'}) + .inputValidator((data: {organizationId: string, userId: string}) => data) + .handler(async ({data: {organizationId, userId}}) => { + return getTokens(organizationId, userId); +}) + +export const createTokenFn = createServerFn({method: 'POST'}) + .inputValidator((data: {organizationId: string, userId: string, name: string, expiresAt: string | null}) => data) + .handler(async ({data: {organizationId, userId, name, expiresAt}}) => { + return createToken(organizationId, userId, name, expiresAt); +}) + +export const verifyTokenFn = createServerFn({method: 'POST'}) + .inputValidator((data: { token: string}) => data) + .handler(async ({data: { token}}) => { + return verifyToken( token); +}) + +export const deleteTokenFn = createServerFn({method: 'POST'}) + .inputValidator((data: {organizationId: string, userId: string, tokenId: string}) => data) + .handler(async ({data: {organizationId, userId, tokenId}}) => { + return deleteToken(organizationId, userId, tokenId); +}) \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/ui/src/router.tsx new/digger-cli-0.6.131/ui/src/router.tsx --- old/digger-cli-0.6.130/ui/src/router.tsx 2025-10-28 20:58:52.000000000 +0100 +++ new/digger-cli-0.6.131/ui/src/router.tsx 2025-10-29 16:27:04.000000000 +0100 @@ -1,6 +1,6 @@ import { createRouter } from '@tanstack/react-router'; import { routeTree } from './routeTree.gen'; -import { terraformRoute } from '@/routes/manual/terraformWellknown'; +import { terraformRoute } from '@/routes/manual/terraformWellKnown'; const existingChildren = (routeTree as any).children ?? [] // internal but fine diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/ui/src/routes/__root.tsx new/digger-cli-0.6.131/ui/src/routes/__root.tsx --- old/digger-cli-0.6.130/ui/src/routes/__root.tsx 2025-10-28 20:58:52.000000000 +0100 +++ new/digger-cli-0.6.131/ui/src/routes/__root.tsx 2025-10-29 16:27:04.000000000 +0100 @@ -11,7 +11,7 @@ import { GitBranch, Folders, Waves, Settings, CreditCard, LogOut } from 'lucide-react'; import globalCssUrl from '@/styles/global.css?url' import { Toaster } from '@/components/ui/toaster'; -import { getPublicServerConfig } from '@/lib/env.server'; +import { getPublicServerConfig, type Env } from '@/lib/env.server'; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/ui/src/routes/_authenticated/_dashboard/dashboard/settings.tokens.tsx new/digger-cli-0.6.131/ui/src/routes/_authenticated/_dashboard/dashboard/settings.tokens.tsx --- old/digger-cli-0.6.130/ui/src/routes/_authenticated/_dashboard/dashboard/settings.tokens.tsx 2025-10-28 20:58:52.000000000 +0100 +++ new/digger-cli-0.6.131/ui/src/routes/_authenticated/_dashboard/dashboard/settings.tokens.tsx 2025-10-29 16:27:04.000000000 +0100 @@ -2,25 +2,100 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' +import { Label } from '@/components/ui/label' +import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog' +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' import { useState } from 'react' +import { createTokenFn, deleteTokenFn, getTokensFn } from '@/api/tokens_serverFunctions' +import { useToast } from '@/hooks/use-toast' +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' export const Route = createFileRoute( '/_authenticated/_dashboard/dashboard/settings/tokens', )({ component: RouteComponent, + loader: async ({ context }) => { + const { user, organisationId } = context; + const tokens = await getTokensFn({data: {organizationId: organisationId, userId: user?.id || ''}}) + return { tokens, user, organisationId } + } }) function RouteComponent() { - const [tokens, setTokens] = useState<string[]>([]) + const { tokens, user, organisationId } = Route.useLoaderData() + const [tokenList, setTokenList] = useState<typeof tokens>(tokens) const [newToken, setNewToken] = useState('') + const [open, setOpen] = useState(false) + const [nickname, setNickname] = useState('') + const [expiry, setExpiry] = useState<'1_week' | '30_days' | 'no_expiry'>('1_week') + const [submitting, setSubmitting] = useState(false) + const { toast } = useToast() + const computeExpiry = (value: '1_week' | '30_days' | 'no_expiry'): string | null => { + console.log('value', value) + if (value === 'no_expiry') return null + if (value === '1_week') return `${7*24}h` + if (value === '30_days') return `${30*24}h` + return `${7*24}h` + } + + function formatDateString(value?: string | null) { + if (!value) return 'ā' + const d = new Date(value) + if (isNaN(d.getTime())) return String(value) + return d.toLocaleDateString('en-US', { + year: 'numeric', + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit' + }) + } + + function isTokenExpired(token: any) { + if (token?.status && token.status !== 'active') return true + if (token?.expires_at) { + const exp = new Date(token.expires_at) + if (!isNaN(exp.getTime()) && exp.getTime() < Date.now()) return true + } + return false + } - const generateToken = () => { - // This is a placeholder - implement actual token generation logic - const token = `digger_${Math.random().toString(36).substring(2)}` - setTokens([...tokens, token]) - setNewToken(token) + const onConfirmGenerate = async () => { + setSubmitting(true) + try { + const expiresAt = computeExpiry(expiry) + const created = await createTokenFn({data: {organizationId: organisationId, userId: user?.id || '', name: nickname || 'New Token', expiresAt}}) + if (created && created.token) { + setNewToken(created.token) + } + setOpen(false) + setNickname('') + setExpiry('no_expiry') + const newTokenList = await getTokensFn({data: {organizationId: organisationId, userId: user?.id || ''}}) + setTokenList(newTokenList) + } finally { + setSubmitting(false) + } } + const handleRevokeToken = async (tokenId: string) => { + deleteTokenFn({data: {organizationId: organisationId, userId: user?.id || '', tokenId: tokenId}}).then(() => { + toast({ + title: 'Token revoked', + description: 'The token has been revoked', + }) + }).catch((error) => { + toast({ + title: 'Failed to revoke token', + description: error.message, + variant: 'destructive', + }) + }).finally(async () => { + setSubmitting(false) + const newTokenList = await getTokensFn({data: {organizationId: organisationId, userId: user?.id || ''}}) + setTokenList(newTokenList) + }) + } return ( <Card> <CardHeader> @@ -31,7 +106,40 @@ </CardHeader> <CardContent className="space-y-4"> <div className="flex space-x-4"> - <Button onClick={generateToken}>Generate New Token</Button> + <Dialog open={open} onOpenChange={setOpen}> + <DialogTrigger asChild> + <Button>Generate New Token</Button> + </DialogTrigger> + <DialogContent> + <DialogHeader> + <DialogTitle>Generate API Token</DialogTitle> + <DialogDescription>Provide a nickname and choose an expiry.</DialogDescription> + </DialogHeader> + <div className="space-y-4"> + <div className="space-y-2"> + <Label htmlFor="nickname">Nickname</Label> + <Input id="nickname" placeholder="e.g. CI token" value={nickname} onChange={(e) => setNickname(e.target.value)} /> + </div> + <div className="space-y-2"> + <Label>Expiry</Label> + <Select value={expiry} onValueChange={(v) => setExpiry(v as typeof expiry)}> + <SelectTrigger> + <SelectValue placeholder="Select expiry" /> + </SelectTrigger> + <SelectContent> + <SelectItem value="1_week">1 week</SelectItem> + <SelectItem value="30_days">30 days</SelectItem> + <SelectItem value="no_expiry">No expiry</SelectItem> + </SelectContent> + </Select> + </div> + </div> + <DialogFooter> + <Button variant="outline" onClick={() => setOpen(false)} disabled={submitting}>Cancel</Button> + <Button onClick={onConfirmGenerate} disabled={submitting || (!nickname && expiry === 'no_expiry')}>{submitting ? 'Generating...' : 'Generate'}</Button> + </DialogFooter> + </DialogContent> + </Dialog> </div> {newToken && ( <div className="space-y-2"> @@ -46,23 +154,43 @@ )} <div className="space-y-2"> <h4 className="text-sm font-medium">Your Tokens</h4> - {tokens.length === 0 ? ( + {tokenList.length === 0 ? ( <p className="text-sm text-muted-foreground">No tokens generated yet</p> ) : ( - <div className="space-y-2"> - {tokens.map((token, index) => ( - <div key={index} className="flex items-center justify-between"> - <code className="text-sm">ā¢ā¢ā¢ā¢ā¢ā¢ā¢ā¢ā¢ā¢ā¢{token.slice(-4)}</code> - <Button - variant="destructive" - size="sm" - onClick={() => setTokens(tokens.filter((_, i) => i !== index))} - > - Revoke - </Button> - </div> - ))} - </div> + <Table> + <TableHeader> + <TableRow> + <TableHead className="text-left">Name</TableHead> + <TableHead className="text-left">Token</TableHead> + <TableHead className="text-left">Expires</TableHead> + <TableHead className="text-left">Created</TableHead> + <TableHead className="text-left">Actions</TableHead> + </TableRow> + </TableHeader> + <TableBody> + {tokenList.map((token, index) => ( + <TableRow key={index}> + <TableCell className="font-medium">{token.name}</TableCell> + <TableCell>ā¢ā¢ā¢ā¢ā¢ā¢ā¢ā¢ā¢ā¢ā¢{token.token.slice(-4)}</TableCell> + <TableCell> + {isTokenExpired(token) + ? <span className="text-destructive">This token has expired</span> + : (token.expires_at ? formatDateString(token.expires_at) : 'No expiry')} + </TableCell> + <TableCell>{formatDateString(token.created_at)}</TableCell> + <TableCell> + <Button + variant="destructive" + size="sm" + onClick={() => handleRevokeToken(token.id)} + > + Revoke + </Button> + </TableCell> + </TableRow> + ))} + </TableBody> + </Table> )} </div> </CardContent> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/ui/src/routes/_authenticated/_dashboard/dashboard/settings.tsx new/digger-cli-0.6.131/ui/src/routes/_authenticated/_dashboard/dashboard/settings.tsx --- old/digger-cli-0.6.130/ui/src/routes/_authenticated/_dashboard/dashboard/settings.tsx 2025-10-28 20:58:52.000000000 +0100 +++ new/digger-cli-0.6.131/ui/src/routes/_authenticated/_dashboard/dashboard/settings.tsx 2025-10-29 16:27:04.000000000 +0100 @@ -9,15 +9,14 @@ const { user, organisationId, role } = context return { user, organisationId, role } }, - beforeLoad: ({ location, search }) => { + beforeLoad: (({ location, search }) => { if (location.pathname === '/dashboard/settings') { throw redirect({ - to: '.', + to: '/dashboard/settings/user', search }) } - return {} - } + }) as any }) function RouteComponent() { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/ui/src/routes/app/settings.tokens.tsx new/digger-cli-0.6.131/ui/src/routes/app/settings.tokens.tsx --- old/digger-cli-0.6.130/ui/src/routes/app/settings.tokens.tsx 2025-10-28 20:58:52.000000000 +0100 +++ new/digger-cli-0.6.131/ui/src/routes/app/settings.tokens.tsx 2025-10-29 16:27:04.000000000 +0100 @@ -4,7 +4,7 @@ server: { handlers: { GET: async ({ request }) => { - return new redirect({ to: '/dashboard/settings/tokens' }) + return redirect({ to: '/dashboard/settings/tokens' }) } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/digger-cli-0.6.130/ui/src/routes/tfe/$.tsx new/digger-cli-0.6.131/ui/src/routes/tfe/$.tsx --- old/digger-cli-0.6.130/ui/src/routes/tfe/$.tsx 2025-10-28 20:58:52.000000000 +0100 +++ new/digger-cli-0.6.131/ui/src/routes/tfe/$.tsx 2025-10-29 16:27:04.000000000 +0100 @@ -1,8 +1,21 @@ +import { verifyTokenFn } from '@/api/tokens_serverFunctions'; import { createFileRoute } from '@tanstack/react-router' async function handler({ request }) { const url = new URL(request.url); + try { + const token = request.headers.get('authorization')?.split(' ')[1] + const tokenValidation = await verifyTokenFn({data: { token: token}}) + if (!tokenValidation.valid) { + return new Response('Unauthorized', { status: 401 }) + } + } catch (error) { + console.error('Error verifying token', error) + return new Response('Unauthorized', { status: 401 }) + } + + // important: we need to set these to allow the statesman backend to return the correct URL to opentofu or terraform clients const outgoingHeaders = new Headers(request.headers); const originalHost = outgoingHeaders.get('host') ?? ''; ++++++ digger-cli.obsinfo ++++++ --- /var/tmp/diff_new_pack.2iNMUE/_old 2025-11-02 22:33:48.809792948 +0100 +++ /var/tmp/diff_new_pack.2iNMUE/_new 2025-11-02 22:33:48.813793115 +0100 @@ -1,5 +1,5 @@ name: digger-cli -version: 0.6.130 -mtime: 1761681532 -commit: 49717065b51bd76dd7568d19f2c3cfb214973cdc +version: 0.6.131 +mtime: 1761751624 +commit: e271ff07c354d40a3405c008883f7313e44c3bee ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/digger-cli/vendor.tar.gz /work/SRC/openSUSE:Factory/.digger-cli.new.1980/vendor.tar.gz differ: char 13, line 1
