-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: add new environment variables to .env.dist file fix(route.ts): add authentication check to GET method feat(route.ts): add authentication middleware to auth route refactor(layout.tsx): change type of children prop to React.ReactNode feat(page.tsx): add authentication check to HomePage component feat(auth.ts): add authentication providers and callbacks feat(SidebarDesktop.tsx): add LogoutButton component to user profile section feat(HomeButton.tsx): add LoginButton and LogoutButton components feat(middleware.ts): add middleware to protect all routes except for API and static files feat(next.config.js): add external packages to serverComponentsExternalPackages option in experimental config feat(package.json): update next-auth and octokit dependencies to latest versions to improve security and functionality chore(package.json): bump version to 1.2.0 to reflect changes made in this commit
- Loading branch information
1 parent
c612b08
commit 64e76bf
Showing
12 changed files
with
784 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { authOptions } from "@/lib/auth"; | ||
import NextAuth from "next-auth"; | ||
|
||
const handler = NextAuth(authOptions); | ||
|
||
export { handler as GET, handler as POST }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
'use client'; | ||
|
||
import { signIn, signOut } from 'next-auth/react'; | ||
|
||
export function LoginButton() { | ||
return ( | ||
<button | ||
onClick={() => signIn()} | ||
className="rounded-md bg-indigo-500 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-400" | ||
> | ||
Sign in | ||
</button> | ||
); | ||
} | ||
|
||
export function LogoutButton() { | ||
return ( | ||
<button | ||
onClick={() => signOut({ callbackUrl: '/' })} | ||
className="rounded-md bg-indigo-500 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-400" | ||
> | ||
Sign Out | ||
</button> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import type { NextAuthOptions, Profile } from "next-auth"; | ||
import AtlassianProvider from "next-auth/providers/atlassian"; | ||
import AzureADProvider from "next-auth/providers/azure-ad"; | ||
import CognitoProvider from "next-auth/providers/cognito"; | ||
import GithubProvider from "next-auth/providers/github"; | ||
import GitlabProvider from "next-auth/providers/gitlab"; | ||
import GoogleProvider from "next-auth/providers/google"; | ||
import KeycloakProvider from "next-auth/providers/keycloak"; | ||
import { Octokit } from "octokit"; | ||
|
||
type ExtendedProfile = Profile & { [key: string]: any; }; | ||
|
||
const getProviders = () => { | ||
let providers = []; | ||
|
||
if (process.env.GITHUB_ID && process.env.GITHUB_SECRET) { | ||
providers.push(GithubProvider({ | ||
clientId: process.env.GITHUB_ID, | ||
clientSecret: process.env.GITHUB_SECRET, | ||
authorization: { | ||
url: "https://github.com/login/oauth/authorize", | ||
params: { scope: "read:user user:email user read:org" }, | ||
}, | ||
})); | ||
} | ||
|
||
if (process.env.ATLASSIAN_ID && process.env.ATLASSIAN_SECRET) { | ||
providers.push(AtlassianProvider({ | ||
clientId: process.env.ATLASSIAN_ID, | ||
clientSecret: process.env.ATLASSIAN_SECRET, | ||
})); | ||
} | ||
|
||
if (process.env.GOOGLE_ID && process.env.GOOGLE_SECRET) { | ||
providers.push(GoogleProvider({ | ||
clientId: process.env.GOOGLE_ID, | ||
clientSecret: process.env.GOOGLE_SECRET, | ||
})); | ||
} | ||
|
||
if (process.env.COGNITO_ID && process.env.COGNITO_SECRET) { | ||
providers.push(CognitoProvider({ | ||
clientId: process.env.COGNITO_ID, | ||
clientSecret: process.env.COGNITO_SECRET, | ||
issuer: process.env.COGNITO_ISSUER, | ||
})); | ||
} | ||
|
||
if (process.env.GITLAB_ID && process.env.GITLAB_SECRET) { | ||
providers.push(GitlabProvider({ | ||
clientId: process.env.GITLAB_ID, | ||
clientSecret: process.env.GITLAB_SECRET, | ||
})); | ||
} | ||
|
||
if (process.env.KEYCLOAK_ID && process.env.KEYCLOAK_SECRET) { | ||
providers.push(KeycloakProvider({ | ||
clientId: process.env.KEYCLOAK_ID, | ||
clientSecret: process.env.KEYCLOAK_SECRET, | ||
issuer: process.env.KEYCLOAK_ISSUER, | ||
})); | ||
} | ||
|
||
if (process.env.AZURE_AD_CLIENT_ID && process.env.AZURE_AD_CLIENT_SECRET) { | ||
providers.push(AzureADProvider({ | ||
clientId: process.env.AZURE_AD_CLIENT_ID, | ||
clientSecret: process.env.AZURE_AD_CLIENT_SECRET, | ||
tenantId: process.env.AZURE_AD_TENANT_ID, | ||
})); | ||
} | ||
|
||
return providers; | ||
}; | ||
|
||
export const authOptions: NextAuthOptions = { | ||
session: { | ||
strategy: "jwt", | ||
}, | ||
debug: process.env.NEXTAUTH_DEBUG === "true", | ||
providers: getProviders(), | ||
callbacks: { | ||
async signIn({ user, account, profile, email, credentials }) { | ||
const extendedProfile = profile as ExtendedProfile; | ||
|
||
if (account?.provider === "google" && process.env.GOOGLE_DOMAINS) { | ||
const domains = process.env.GOOGLE_DOMAINS.split(","); | ||
const emailDomain = extendedProfile?.email?.split("@")[1]; | ||
return extendedProfile?.email_verified && emailDomain && domains.includes(emailDomain); | ||
} | ||
|
||
if (account?.provider === "github" && process.env.GITHUB_ORGS) { | ||
const allowedOrgs = process.env.GITHUB_ORGS.split(","); | ||
const token = account.access_token; | ||
const octokit = new Octokit({ auth: token, userAgent: "airbroke" }); | ||
const orgsResponse = await octokit.rest.orgs.listForAuthenticatedUser(); | ||
const userOrgs = orgsResponse.data.map(org => org.login); | ||
|
||
// Check if the user is part of at least one of the allowed organizations | ||
return userOrgs.some(org => allowedOrgs.includes(org)); | ||
} | ||
return true; | ||
}, | ||
}, | ||
theme: { | ||
colorScheme: "dark", // "auto" | "dark" | "light" | ||
brandColor: "#192231", // Hex color code | ||
logo: "", // Absolute URL to image | ||
buttonText: "" // Hex color code | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export { default } from "next-auth/middleware"; | ||
|
||
export const config = { | ||
matcher: [ | ||
/* | ||
* Match all request paths except for the ones starting with: | ||
* - api (API routes) | ||
* - _next/static (static files) | ||
* - _next/image (image optimization files) | ||
* - favicon.ico (favicon file) | ||
* - the homepage ("/") | ||
*/ | ||
'/((?!api|_next/static|_next/image|favicon.ico).+)', | ||
], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.