Skip to content

Commit

Permalink
added test for zitadel
Browse files Browse the repository at this point in the history
  • Loading branch information
WilsonLe committed Dec 15, 2024
1 parent b2d5c39 commit bc33d36
Show file tree
Hide file tree
Showing 12 changed files with 294 additions and 72 deletions.
54 changes: 0 additions & 54 deletions .github/workflows/test-google-oauth.yml

This file was deleted.

101 changes: 101 additions & 0 deletions .github/workflows/test-oauth.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
name: Test OAuth

on:
pull_request:
branches: [main]
push:
branches: [main]
workflow_dispatch:

jobs:
test-google-oauth:
runs-on: ubuntu-latest
env:
##########################################################################
# App Config
##########################################################################
NEXT_PUBLIC_URL: "http://localhost:3000"
DATABASE_URI: "file:./payload-oauth2.db"
PAYLOAD_SECRET: "hellohereisasecretforyou"

##########################################################################
# Google OAuth Config
##########################################################################
GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }}
GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }}

##########################################################################
# Test Config
##########################################################################
# Optional: Set to "true" to run test browser in headless mode
HEADLESS: true

##########################################################################
# Google Test Account
##########################################################################
# Required: Google Test Account Email
GOOGLE_TEST_EMAIL: ${{ secrets.GOOGLE_TEST_EMAIL }}

# Required: Google Test Account Password
GOOGLE_TEST_PASSWORD: ${{ secrets.GOOGLE_TEST_PASSWORD }}

steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "pnpm"
- run: |
pnpx puppeteer browsers install chrome
- run: pnpm install
- run: pnpm test
test-zitadel-oauth:
runs-on: ubuntu-latest
env:
##########################################################################
# App Config
##########################################################################
NEXT_PUBLIC_URL: "http://localhost:3000"
DATABASE_URI: "file:./payload-oauth2.db"
PAYLOAD_SECRET: "hellohereisasecretforyou"

##########################################################################
# Zitadel OAuth Config
##########################################################################
ZITADEL_CLIENT_ID: ${{ secrets.ZITADEL_CLIENT_ID }}
ZITADEL_CLIENT_SECRET: ${{ secrets.ZITADEL_CLIENT_SECRET }}
ZITADEL_TOKEN_ENDPOINT: ${{ secrets.ZITADEL_TOKEN_ENDPOINT }}
ZITADEL_AUTHORIZATION_URL: ${{ secrets.ZITADEL_AUTHORIZATION_URL }}
ZITADEL_USERINFO_ENDPOINT: ${{ secrets.ZITADEL_USERINFO_ENDPOINT }}

##########################################################################
# Test Config
##########################################################################
# Optional: Set to "true" to run test browser in headless mode
HEADLESS: true

##########################################################################
# Zitadel Test Account
##########################################################################
# Required: Zitadel Test Account Email
ZITADEL_TEST_EMAIL: ${{ secrets.ZITADEL_TEST_EMAIL }}

# Required: Zitadel Test Account Password
ZITADEL_TEST_PASSWORD: ${{ secrets.ZITADEL_TEST_PASSWORD }}

steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "pnpm"
- run: |
pnpx puppeteer browsers install chrome
- run: pnpm install
- run: pnpm test
11 changes: 10 additions & 1 deletion dev/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,14 @@ NEXT_PUBLIC_URL=http://localhost:3000
# Optional: Google OAuth2 Client ID, not activated if not set
# GOOGLE_CLIENT_ID=oauth2-client-id

# Required: Google OAuth2 Client Secret, not activated if not set
# Optional: Google OAuth2 Client Secret, not activated if not set
# GOOGLE_CLIENT_SECRET=oauth2-client-secret

################################################################################
# zitadel oauth config
################################################################################
# optional: google oauth2 client id, not activated if not set
ZITADEL_CLIENT_ID=298062958548846024

# optional: google oauth2 client secret, not activated if not set
ZITADEL_CLIENT_SECRET=q2isqvfws3kg0af4ksiek3jigwre5utfoxgwkjj7mkbsmpgdyv1abyq6jcgpakch
6 changes: 4 additions & 2 deletions dev/src/app/(payload)/admin/importMap.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { OAuthLoginButton as OAuthLoginButton_cd47d145aed4cb23589a094917bd46e9 } from 'src/components/OAuthLoginButton'
import { GoogleOAuthLoginButton as GoogleOAuthLoginButton_143f92647bcb7528bfe1082a22fc4d4e } from 'src/components/GoogleOAuthLoginButton'
import { ZitadelOAuthLoginButton as ZitadelOAuthLoginButton_2b344d0256ae0172631ef421761722bb } from 'src/components/ZitadelOAuthLoginButton'

export const importMap = {
"src/components/OAuthLoginButton#OAuthLoginButton": OAuthLoginButton_cd47d145aed4cb23589a094917bd46e9
"src/components/GoogleOAuthLoginButton#GoogleOAuthLoginButton": GoogleOAuthLoginButton_143f92647bcb7528bfe1082a22fc4d4e,
"src/components/ZitadelOAuthLoginButton#ZitadelOAuthLoginButton": ZitadelOAuthLoginButton_2b344d0256ae0172631ef421761722bb
}
8 changes: 2 additions & 6 deletions dev/src/collections/Users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,8 @@ import { CollectionConfig } from "payload";

const Users: CollectionConfig = {
slug: "users",
auth: {
disableLocalStrategy: true,
},
admin: {
useAsTitle: "email",
},
auth: { disableLocalStrategy: true },
admin: { useAsTitle: "email" },
fields: [{ name: "email", type: "email", required: true }],
};

Expand Down
11 changes: 11 additions & 0 deletions dev/src/components/GoogleOAuthLoginButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"use client";
export const GoogleOAuthLoginButton: React.FC = () => (
<a href="/api/users/oauth/google">
<button
className="btn btn--icon-style-without-border btn--size-large btn--withoutPopup btn--style-primary btn--withoutPopup"
style={{ width: "100%" }}
>
Continue With Google
</button>
</a>
);
6 changes: 0 additions & 6 deletions dev/src/components/OAuthLoginButton.tsx

This file was deleted.

11 changes: 11 additions & 0 deletions dev/src/components/ZitadelOAuthLoginButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"use client";
export const ZitadelOAuthLoginButton: React.FC = () => (
<a href="/api/users/oauth/zitadel">
<button
className="btn btn--icon-style-without-border btn--size-large btn--withoutPopup btn--style-primary btn--withoutPopup"
style={{ width: "100%" }}
>
Continue With Zitadel
</button>
</a>
);
51 changes: 50 additions & 1 deletion dev/src/payload.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ export default buildConfig({
baseDir: path.resolve(dirname),
},
components: {
afterLogin: ["src/components/OAuthLoginButton#OAuthLoginButton"],
afterLogin: [
"src/components/GoogleOAuthLoginButton#GoogleOAuthLoginButton",
"src/components/ZitadelOAuthLoginButton#ZitadelOAuthLoginButton",
],
},
user: Users.slug,
},
Expand All @@ -44,6 +47,7 @@ export default buildConfig({
clientId: process.env.GOOGLE_CLIENT_ID || "",
clientSecret: process.env.GOOGLE_CLIENT_SECRET || "",
authorizePath: "/oauth/google",
callbackPath: "/oauth/google/callback",
authCollection: "users",
tokenEndpoint: "https://oauth2.googleapis.com/token",
scopes: [
Expand All @@ -68,6 +72,51 @@ export default buildConfig({
return "/admin/login";
},
}),
////////////////////////////////////////////////////////////////////////////
// Zitadel OAuth
////////////////////////////////////////////////////////////////////////////
OAuth2Plugin({
enabled:
typeof process.env.ZITADEL_CLIENT_ID === "string" &&
typeof process.env.ZITADEL_CLIENT_SECRET === "string" &&
typeof process.env.ZITADEL_TOKEN_ENDPOINT === "string" &&
typeof process.env.ZITADEL_AUTHORIZATION_URL === "string" &&
typeof process.env.ZITADEL_USERINFO_ENDPOINT === "string",
strategyName: "zitadel",
useEmailAsIdentity: true,
serverURL: process.env.NEXT_PUBLIC_URL || "http://localhost:3000",
clientId: process.env.ZITADEL_CLIENT_ID || "",
clientSecret: process.env.ZITADEL_CLIENT_SECRET || "",
authorizePath: "/oauth/zitadel",
callbackPath: "/oauth/zitadel/callback",
authCollection: "users",
tokenEndpoint: process.env.ZITADEL_TOKEN_ENDPOINT || "",
scopes: [
"openid",
"profile",
"email",
"offline_access",
"urn:zitadel:iam:user:metadata",
],
providerAuthorizationUrl: process.env.ZITADEL_AUTHORIZATION_URL || "",
getUserInfo: async (accessToken: string) => {
const response = await fetch(
process.env.ZITADEL_USERINFO_ENDPOINT || "",
{
headers: { Authorization: `Bearer ${accessToken}` },
},
);
const user = await response.json();
return { email: user.email, sub: user.sub };
},
successRedirect: (req) => {
return "/admin";
},
failureRedirect: (req, err) => {
req.payload.logger.error(err);
return "/admin/login";
},
}),
],
sharp,
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"dev:build": "cross-env NODE_OPTIONS=--no-deprecation next build dev",
"dev:start": "cross-env NODE_OPTIONS=--no-deprecation next start dev",
"build": "tsc",
"test": "cd test && jest --config=./jest.config.js",
"test": "cd test && jest --config=./jest.config.js --runInBand",
"format": "prettier --write src dev",
"payload": "cd dev && cross-env NODE_OPTIONS=--no-deprecation payload",
"dev:lint": "cd dev && cross-env NODE_OPTIONS=--no-deprecation next lint",
Expand Down
2 changes: 1 addition & 1 deletion test/google.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ describe("Google OAuth2 Integration", () => {
// logout by wiping cookies
const cookies = await page.cookies();
for (const cookie of cookies) {
await page.deleteCookie(cookie);
await browser.deleteCookie(cookie);
}
console.info("Cookies deleted");
});
Expand Down
Loading

0 comments on commit bc33d36

Please sign in to comment.