diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 404c59ed..5e57b249 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Setup pnpm - uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8 + uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 with: package_json_file: ./frontend/package.json diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 7d54318d..329e27ab 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -60,7 +60,7 @@ jobs: ref: nightly - name: Setup pnpm - uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8 + uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 with: package_json_file: ./frontend/package.json @@ -105,7 +105,7 @@ jobs: ref: nightly - name: Setup pnpm - uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8 + uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 with: package_json_file: ./frontend/package.json @@ -173,8 +173,8 @@ jobs: labels: ${{ steps.meta.outputs.labels }} tags: ghcr.io/${{ github.repository_owner }}/tinyauth outputs: type=image,push-by-digest=true,name-canonical=true,push=true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: type=gha,scope=buildkit-amd64 + cache-to: type=gha,mode=max,scope=buildkit-amd64 github-token: ${{ secrets.GITHUB_TOKEN }} build-args: | VERSION=${{ needs.generate-metadata.outputs.VERSION }} @@ -232,8 +232,8 @@ jobs: tags: ghcr.io/${{ github.repository_owner }}/tinyauth outputs: type=image,push-by-digest=true,name-canonical=true,push=true file: Dockerfile.distroless - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: type=gha,scope=buildkit-distroless-amd64 + cache-to: type=gha,mode=max,scope=buildkit-distroless-amd64 github-token: ${{ secrets.GITHUB_TOKEN }} build-args: | VERSION=${{ needs.generate-metadata.outputs.VERSION }} @@ -289,8 +289,8 @@ jobs: labels: ${{ steps.meta.outputs.labels }} tags: ghcr.io/${{ github.repository_owner }}/tinyauth outputs: type=image,push-by-digest=true,name-canonical=true,push=true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: type=gha,scope=buildkit-arm64 + cache-to: type=gha,mode=max,scope=buildkit-arm64 github-token: ${{ secrets.GITHUB_TOKEN }} build-args: | VERSION=${{ needs.generate-metadata.outputs.VERSION }} @@ -348,8 +348,8 @@ jobs: tags: ghcr.io/${{ github.repository_owner }}/tinyauth outputs: type=image,push-by-digest=true,name-canonical=true,push=true file: Dockerfile.distroless - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: type=gha,scope=buildkit-distroless-arm64 + cache-to: type=gha,mode=max,scope=buildkit-distroless-arm64 github-token: ${{ secrets.GITHUB_TOKEN }} build-args: | VERSION=${{ needs.generate-metadata.outputs.VERSION }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0af56596..fa8f721b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -36,7 +36,7 @@ jobs: uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Setup pnpm - uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8 + uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 with: package_json_file: ./frontend/package.json @@ -78,7 +78,7 @@ jobs: uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Setup pnpm - uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8 + uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 with: package_json_file: ./frontend/package.json @@ -143,14 +143,14 @@ jobs: labels: ${{ steps.meta.outputs.labels }} tags: ghcr.io/${{ github.repository_owner }}/tinyauth outputs: type=image,push-by-digest=true,name-canonical=true,push=true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: type=gha,scope=buildkit-amd64 + cache-to: type=gha,mode=max,scope=buildkit-amd64 github-token: ${{ secrets.GITHUB_TOKEN }} build-args: | VERSION=${{ needs.generate-metadata.outputs.VERSION }} COMMIT_HASH=${{ needs.generate-metadata.outputs.COMMIT_HASH }} BUILD_TIMESTAMP=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }} - LDFLAGS="-s -w" + LDFLAGS=-s -w - name: Export digest run: | @@ -200,14 +200,14 @@ jobs: tags: ghcr.io/${{ github.repository_owner }}/tinyauth outputs: type=image,push-by-digest=true,name-canonical=true,push=true file: Dockerfile.distroless - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: type=gha,scope=buildkit-distroless-amd64 + cache-to: type=gha,mode=max,scope=buildkit-distroless-amd64 github-token: ${{ secrets.GITHUB_TOKEN }} build-args: | VERSION=${{ needs.generate-metadata.outputs.VERSION }} COMMIT_HASH=${{ needs.generate-metadata.outputs.COMMIT_HASH }} BUILD_TIMESTAMP=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }} - LDFLAGS="-s -w" + LDFLAGS=-s -w - name: Export digest run: | @@ -255,14 +255,14 @@ jobs: labels: ${{ steps.meta.outputs.labels }} tags: ghcr.io/${{ github.repository_owner }}/tinyauth outputs: type=image,push-by-digest=true,name-canonical=true,push=true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: type=gha,scope=buildkit-arm64 + cache-to: type=gha,mode=max,scope=buildkit-arm64 github-token: ${{ secrets.GITHUB_TOKEN }} build-args: | VERSION=${{ needs.generate-metadata.outputs.VERSION }} COMMIT_HASH=${{ needs.generate-metadata.outputs.COMMIT_HASH }} BUILD_TIMESTAMP=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }} - LDFLAGS="-s -w" + LDFLAGS=-s -w - name: Export digest run: | @@ -312,14 +312,14 @@ jobs: tags: ghcr.io/${{ github.repository_owner }}/tinyauth outputs: type=image,push-by-digest=true,name-canonical=true,push=true file: Dockerfile.distroless - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: type=gha,scope=buildkit-distroless-arm64 + cache-to: type=gha,mode=max,scope=buildkit-distroless-arm64 github-token: ${{ secrets.GITHUB_TOKEN }} build-args: | VERSION=${{ needs.generate-metadata.outputs.VERSION }} COMMIT_HASH=${{ needs.generate-metadata.outputs.COMMIT_HASH }} BUILD_TIMESTAMP=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }} - LDFLAGS="-s -w" + LDFLAGS=-s -w - name: Export digest run: | diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 5ef3741f..4507fdf1 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -38,6 +38,6 @@ jobs: retention-days: 5 - name: Upload to code-scanning - uses: github/codeql-action/upload-sarif@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4 + uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4 with: sarif_file: results.sarif diff --git a/Dockerfile b/Dockerfile index 65f82e2e..aa1a2bcb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -46,7 +46,7 @@ RUN CGO_ENABLED=0 go build -ldflags "${LDFLAGS} \ -X github.com/tinyauthapp/tinyauth/internal/model.BuildTimestamp=${BUILD_TIMESTAMP}" ./cmd/tinyauth # Runner -FROM alpine:3.23 AS runner +FROM alpine:3.24 AS runner WORKDIR /tinyauth diff --git a/frontend/src/lib/hooks/screen-params.ts b/frontend/src/lib/hooks/screen-params.ts index d342d03a..abf3a41a 100644 --- a/frontend/src/lib/hooks/screen-params.ts +++ b/frontend/src/lib/hooks/screen-params.ts @@ -6,7 +6,7 @@ type ScreenParams = { oidc_ticket?: string; oidc_scope?: string; oidc_name?: string; - oidc_show_consent?: boolean; + oidc_prompt?: "none" | "login"; }; const zodScreenParams = z.object({ @@ -15,7 +15,7 @@ const zodScreenParams = z.object({ oidc_ticket: z.string().optional(), oidc_scope: z.string().optional(), oidc_name: z.string().optional(), - oidc_show_consent: z.stringbool().optional(), + oidc_prompt: z.enum(["none", "login"]).optional(), }); export function useScreenParams(params: URLSearchParams): ScreenParams { diff --git a/frontend/src/pages/authorize-page.tsx b/frontend/src/pages/authorize-page.tsx index 5f721217..0f14a583 100644 --- a/frontend/src/pages/authorize-page.tsx +++ b/frontend/src/pages/authorize-page.tsx @@ -91,54 +91,41 @@ export const AuthorizePage = () => { const isOidc = screenParams.login_for === "oidc"; const compiledParams = recompileScreenParams(screenParams); - const { mutate: authorizeMutate, isPending: authorizeIsPending } = - useMutation({ - mutationFn: () => { - return axios.post("/api/oidc/authorize-complete", { - ticket: screenParams.oidc_ticket, - }); - }, - mutationKey: ["authorize", screenParams.oidc_ticket], - onSuccess: (data) => { - toast.info(t("authorizeSuccessTitle"), { - description: t("authorizeSuccessSubtitle"), - }); - window.location.replace(data.data.redirect_uri); - }, - onError: (error) => { - window.location.replace( - `/error?error=${encodeURIComponent(error.message)}`, - ); - }, - }); + // TODO: maybe a better way to do this + const shouldAutoAuthorize = + auth.authenticated && + isOidc && + screenParams.oidc_ticket !== undefined && + screenParams.oidc_scope !== undefined && + screenParams.oidc_prompt === "none"; + + const { mutate: authorizeMutate, isPending: authorizePending } = useMutation({ + mutationFn: () => { + return axios.post("/api/oidc/authorize-complete", { + ticket: screenParams.oidc_ticket, + }); + }, + mutationKey: ["authorize", screenParams.oidc_ticket], + onSuccess: (data) => { + toast.info(t("authorizeSuccessTitle"), { + description: t("authorizeSuccessSubtitle"), + }); + window.location.replace(data.data.redirect_uri); + }, + onError: (error) => { + window.location.replace( + `/error?error=${encodeURIComponent(error.message)}`, + ); + }, + }); useEffect(() => { - if ( - !isOidc || - screenParams.oidc_ticket === undefined || - screenParams.oidc_scope === undefined || - !auth.authenticated - ) { - return; - } - - if (screenParams.oidc_show_consent === false) { + if (shouldAutoAuthorize) { authorizeMutate(); } - }, [ - isOidc, - screenParams.oidc_ticket, - screenParams.oidc_scope, - screenParams.oidc_show_consent, - auth.authenticated, - authorizeMutate, - ]); + }, [shouldAutoAuthorize, authorizeMutate]); - if ( - !isOidc || - screenParams.oidc_ticket === undefined || - screenParams.oidc_scope === undefined - ) { + if (!isOidc || !screenParams.oidc_ticket || !screenParams.oidc_scope) { return ( { ); } - if (!auth.authenticated) { + if (!auth.authenticated || screenParams.oidc_prompt === "login") { return ; } const scopes = screenParams.oidc_scope.split(" ").filter((s) => s.trim() !== "") || []; - if (screenParams.oidc_show_consent === false) { - return ( - - - Authorizing - - You will soon be redirected to your application... - - - - ); - } - return ( @@ -208,12 +182,16 @@ export const AuthorizePage = () => { )} -