diff --git a/.github/workflows/back-test.yaml b/.github/workflows/back-test.yaml index 1bbcf05..b911de9 100644 --- a/.github/workflows/back-test.yaml +++ b/.github/workflows/back-test.yaml @@ -6,8 +6,7 @@ permissions: contents: read jobs: - test: - name: Test + backend-tests: runs-on: ubuntu-latest steps: - name: Check out code @@ -31,6 +30,7 @@ jobs: - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 + if: github.ref == 'refs/heads/main' with: token: ${{ secrets.CODECOV_TOKEN }} files: cover.out diff --git a/.github/workflows/docker-back.yaml b/.github/workflows/docker-back.yaml index 3ae07e0..93ff49b 100644 --- a/.github/workflows/docker-back.yaml +++ b/.github/workflows/docker-back.yaml @@ -8,7 +8,7 @@ on: workflow_dispatch: jobs: - ImageBuild: + BackImageBuild: name: Build openchokin/back Custom Docker Image runs-on: ubuntu-latest steps: @@ -62,7 +62,7 @@ jobs: SucceessNotification: if: ${{ success() }} name: Send Success Message - needs: [ImageBuild] + needs: [BackImageBuild] runs-on: ubuntu-latest steps: - name: Send Message to Slack @@ -80,7 +80,7 @@ jobs: FailureAlert: if: ${{ failure() }} name: Notify failure - needs: [ImageBuild] + needs: [BackImageBuild] runs-on: ubuntu-latest steps: - name: Send Failure Alert to Slack diff --git a/.github/workflows/docker-front.yaml b/.github/workflows/docker-front.yaml index 939291a..2076c66 100644 --- a/.github/workflows/docker-front.yaml +++ b/.github/workflows/docker-front.yaml @@ -8,7 +8,7 @@ on: workflow_dispatch: jobs: - ImageBuild: + FrontImageBuild: name: Build openchokin/front Docker Image runs-on: ubuntu-latest steps: @@ -53,7 +53,7 @@ jobs: SucceessNotification: if: ${{ success() }} name: Send Success Message - needs: [ImageBuild] + needs: [FrontImageBuild] runs-on: ubuntu-latest steps: - name: Send Message to Slack @@ -71,7 +71,7 @@ jobs: FailureAlert: if: ${{ failure() }} name: Notify failure - needs: [ImageBuild] + needs: [FrontImageBuild] runs-on: ubuntu-latest steps: - name: Send Failure Alert to Slack diff --git a/.github/workflows/front-test.yaml b/.github/workflows/front-test.yaml index fc585ed..4ec0876 100644 --- a/.github/workflows/front-test.yaml +++ b/.github/workflows/front-test.yaml @@ -1,9 +1,9 @@ name: Frontend Tests on: - pull_request: workflow_dispatch: + pull_request: jobs: - build: + frontend-buildtests: runs-on: ubuntu-latest steps: - name: checkout diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 98972f4..753d0f4 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -1,9 +1,9 @@ name: Lint on: - pull_request: workflow_dispatch: + pull_request: jobs: - build: + frontend-lint: runs-on: ubuntu-latest steps: - name: checkout diff --git a/front/src/app/api/auth/[...nextauth]/options.ts b/front/src/app/api/auth/[...nextauth]/options.ts index 93fa3c6..0963e2c 100644 --- a/front/src/app/api/auth/[...nextauth]/options.ts +++ b/front/src/app/api/auth/[...nextauth]/options.ts @@ -8,6 +8,7 @@ export const authOptions: NextAuthOptions = { clientId: process.env.ZITADEL_CLIENT_ID as string, clientSecret: process.env.ZITADEL_CLIENT_SECRET as string, issuer: process.env.ZITADEL_URL, + authorization: { params: { scope: "openid email profile offline_access" } }, }), ], callbacks: { @@ -23,22 +24,37 @@ export const authOptions: NextAuthOptions = { account?: any; profile?: any; isNewUser?: boolean; + session?: any; }) => { + //console.log("JWT Callback token", token); if (user) { - token.user = user; - const u = user as any; - token.role = u.role; + token.role = user.role; } if (account) { - token.accessToken = account.access_token; + token.refreshToken = account.refresh_token; token.idToken = account.id_token; + token.expiresAt = account.expires_at; } + else if (new Date() > new Date(token.expiresAt as number * 1000)) { + try { + const { id_token, refresh_token, expires_at } = await refreshIDToken(token.refreshToken as string); + token.idToken = id_token; + token.refreshToken = refresh_token; + token.expiresAt = expires_at; + console.log("Refreshed token"); + } catch (e) { + console.error(e); + return { ...token, error: "RefreshAccessTokenError" as const } + } + } + //console.debug(token); return token; }, session: ({ session, token }: { token: JWT; session?: any }) => { session.user.role = token.role; session.user.idToken = token.idToken; session.user.sub = token.sub; + //console.debug(session); return session; }, }, @@ -46,3 +62,30 @@ export const authOptions: NextAuthOptions = { signIn: '/signin', }, }; + + +const refreshIDToken = async (refreshToken: string) => { + const response = await fetch(`${process.env.ZITADEL_URL}/oauth/v2/token`, { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + body: new URLSearchParams({ + grant_type: "refresh_token", + client_id: process.env.ZITADEL_CLIENT_ID as string, + client_secret: process.env.ZITADEL_CLIENT_SECRET as string, + refresh_token: refreshToken, + }), + }); + const data = await response.json(); + //console.log("Data:", data); + if (!response.ok) { + throw new Error(data.error_description || data.error || "Unknown error"); + } + + return { + id_token: data.id_token, + refresh_token: data.refresh_token, + expires_at: data.expires_at, + } +} \ No newline at end of file diff --git a/front/src/app/next-auth.d.ts b/front/src/app/next-auth.d.ts index 8ac8ebe..0334a89 100644 --- a/front/src/app/next-auth.d.ts +++ b/front/src/app/next-auth.d.ts @@ -3,6 +3,8 @@ import { DefaultSession } from "next-auth"; declare module "next-auth" { interface Session { user: { + refreshToken?: string; + exiresAt?: Date idToken?: string; sub?: string; } & DefaultSession["user"];