feat: Add github authentication provider (#8980)

* feat: Add github authentication provider

* feat: Change callback to always return a token, expect callbackUrl to point to FE

* fix: Return login redirect URLas a 200 response
This commit is contained in:
Stevche Radevski
2024-09-04 13:14:00 +02:00
committed by GitHub
parent fb832072a4
commit af4f8811bd
23 changed files with 717 additions and 46 deletions

View File

@@ -3,7 +3,7 @@
In order to manually test the flow, you can do the following:
1. Register an app in `https://console.cloud.google.com/apis/credentials/consent`
2. Generate clientID and clientSecret credentials in the console
2. Generate clientId and clientSecret credentials in the console
3. Replace the values in the test with your credentials
4. Remove the `server.listen()` call
5. Run the tests, get the `location` value from the `authenticate` test, open the browser

View File

@@ -78,10 +78,9 @@ describe("Google auth provider", () => {
logger: console as any,
},
{
clientID: "test",
clientId: "test",
clientSecret: "test",
successRedirectUrl: baseUrl,
callbackURL: `${baseUrl}/auth/google/callback`,
callbackUrl: `${baseUrl}/auth/google/callback`,
}
)
@@ -99,7 +98,7 @@ describe("Google auth provider", () => {
let msg = ""
try {
GoogleAuthService.validateOptions({
clientID: "test",
clientId: "test",
clientSecret: "test",
} as any)
} catch (e) {
@@ -162,6 +161,9 @@ describe("Google auth provider", () => {
],
}
}),
update: jest.fn().mockImplementation(() => {
return {}
}),
}
const res = await googleService.validateCallback(
@@ -175,7 +177,6 @@ describe("Google auth provider", () => {
expect(res).toEqual({
success: true,
successRedirectUrl: baseUrl,
authIdentity: {
provider_identities: [
{
@@ -202,6 +203,9 @@ describe("Google auth provider", () => {
create: jest.fn().mockImplementation(() => {
return {}
}),
update: jest.fn().mockImplementation(() => {
return {}
}),
}
const res = await googleService.validateCallback(
@@ -215,7 +219,6 @@ describe("Google auth provider", () => {
expect(res).toEqual({
success: true,
successRedirectUrl: baseUrl,
authIdentity: {
provider_identities: [
{

View File

@@ -20,15 +20,15 @@ export class GoogleAuthService extends AbstractAuthModuleProvider {
protected logger_: Logger
static validateOptions(options: GoogleAuthProviderOptions) {
if (!options.clientID) {
throw new Error("Google clientID is required")
if (!options.clientId) {
throw new Error("Google clientId is required")
}
if (!options.clientSecret) {
throw new Error("Google clientSecret is required")
}
if (!options.callbackURL) {
if (!options.callbackUrl) {
throw new Error("Google callbackUrl is required")
}
}
@@ -78,10 +78,10 @@ export class GoogleAuthService extends AbstractAuthModuleProvider {
return { success: false, error: "No code provided" }
}
const params = `client_id=${this.config_.clientID}&client_secret=${
const params = `client_id=${this.config_.clientId}&client_secret=${
this.config_.clientSecret
}&code=${code}&redirect_uri=${encodeURIComponent(
this.config_.callbackURL
this.config_.callbackUrl
)}&grant_type=authorization_code`
const exchangeTokenUrl = new URL(
`https://oauth2.googleapis.com/token?${params}`
@@ -109,7 +109,6 @@ export class GoogleAuthService extends AbstractAuthModuleProvider {
return {
success,
authIdentity,
successRedirectUrl: this.config_.successRedirectUrl,
}
} catch (error) {
return { success: false, error: error.message }
@@ -169,9 +168,9 @@ export class GoogleAuthService extends AbstractAuthModuleProvider {
}
}
private getRedirect({ clientID, callbackURL }: LocalServiceConfig) {
const redirectUrlParam = `redirect_uri=${encodeURIComponent(callbackURL)}`
const clientIdParam = `client_id=${clientID}`
private getRedirect({ clientId, callbackUrl }: LocalServiceConfig) {
const redirectUrlParam = `redirect_uri=${encodeURIComponent(callbackUrl)}`
const clientIdParam = `client_id=${clientId}`
const responseTypeParam = "response_type=code"
const scopeParam = "scope=email+profile+openid"