-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[SOA-59] Social login with ally (#60)
* chore ποΈ : add and configure ally * feat πΈ (be): add routes, controller and methods * styles π : add generic social buttons and divider components * feat πΈ (be): method completion * fix β : minor corrections * chore ποΈ : update README.md * fix β : config corrections based on env * styles π : improve loading/processing feedback on social buttons * fix β : hosteddomain env tweak * chore ποΈ (lint): review lint checking commands * refactor β¨ : clean up dynamic get driver logic * styles π : add enabled flag to social login auth buttons * refactor β¨ (types): utils TW types for prop colors
- Loading branch information
1 parent
c9e00a6
commit 523d4ed
Showing
20 changed files
with
259 additions
and
31 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,7 @@ | ||
#!/usr/bin/env sh | ||
. "$(dirname -- "$0")/_/husky.sh" | ||
echo 'ποΈπ· Styling, formatting and typechecking your project before committing' | ||
|
||
echo 'ποΈπ· Styling, testing and building your project before committing' | ||
|
||
yarn format || | ||
( | ||
echo 'π€πππ€ Prettier Check Failed. Run yarn format, add changes and try to commit again.'; | ||
false; | ||
) | ||
|
||
yarn lint || | ||
( | ||
echo 'π€πππ€ ESLint Check Failed. Make the required changes listed above and try to commit again.' | ||
false; | ||
) | ||
|
||
yarn typecheck || | ||
yarn clean || | ||
( | ||
echo 'π€πππ€ TS Check Failed. Make the required changes listed above and try to commit again.' | ||
echo 'π€πππ€ Pre-checks Failed. Make the required changes listed above and try to commit again.' | ||
false; | ||
) |
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,48 @@ | ||
import User from '#models/user' | ||
import AuthService from '#services/auth_service' | ||
import { randomPasswordGenerator } from '#utils/index' | ||
import { GithubDriver } from '@adonisjs/ally/drivers/github' | ||
import { GoogleDriver } from '@adonisjs/ally/drivers/google' | ||
import { inject } from '@adonisjs/core' | ||
import type { HttpContext } from '@adonisjs/core/http' | ||
import hash from '@adonisjs/core/services/hash' | ||
|
||
@inject() | ||
export default class OAuthController { | ||
constructor(private readonly authService: AuthService) {} | ||
|
||
async redirect(ctx: HttpContext): Promise<void> { | ||
const driver = this.getDriver(ctx) | ||
if (!driver) return ctx.response.notFound() | ||
return driver.redirect() | ||
} | ||
|
||
async callback(ctx: HttpContext): Promise<void> { | ||
const driver = this.getDriver(ctx) | ||
if (!driver) return ctx.response.notFound() | ||
|
||
const details = await driver.user() | ||
|
||
let user = await User.firstOrCreate( | ||
{ | ||
email: details.email, | ||
}, | ||
{ | ||
name: String(details.name).split(' ')[0], | ||
surname: String(details.name).split(' ')[1] ?? '', | ||
email: details.email, | ||
password: await hash.make(randomPasswordGenerator()), | ||
} | ||
) | ||
|
||
await this.authService.authenticate(ctx, user) | ||
} | ||
|
||
private getDriver({ ally, params }: HttpContext): GithubDriver | GoogleDriver | null { | ||
const driver: GithubDriver | GoogleDriver = ally.use(params.provider) | ||
if (!(driver instanceof GithubDriver) && !(driver instanceof GoogleDriver)) { | ||
return null | ||
} | ||
return driver | ||
} | ||
} |
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,34 @@ | ||
import env from '#start/env' | ||
import { defineConfig, services } from '@adonisjs/ally' | ||
|
||
const allyConfig = defineConfig({ | ||
google: services.google({ | ||
clientId: env.get('GOOGLE_CLIENT_ID'), | ||
clientSecret: env.get('GOOGLE_CLIENT_SECRET'), | ||
callbackUrl: | ||
(env.get('NODE_ENV') === 'development' | ||
? 'http://localhost:3000/' | ||
: env.get('PRODUCTION_URL')) + 'auth/google/callback/', | ||
prompt: 'select_account', | ||
hostedDomain: | ||
env.get('NODE_ENV') === 'development' ? 'http://localhost:3000/' : env.get('PRODUCTION_URL'), | ||
display: 'page', | ||
scopes: ['userinfo.email'], | ||
}), | ||
github: services.github({ | ||
clientId: env.get('GITHUB_CLIENT_ID')!, | ||
clientSecret: env.get('GITHUB_CLIENT_SECRET')!, | ||
callbackUrl: | ||
(env.get('NODE_ENV') === 'development' | ||
? 'http://localhost:3000/' | ||
: env.get('PRODUCTION_URL')) + 'auth/github/callback/', | ||
scopes: ['user'], | ||
allowSignup: true, | ||
}), | ||
}) | ||
|
||
export default allyConfig | ||
|
||
declare module '@adonisjs/ally/types' { | ||
interface SocialProviders extends InferSocialProviders<typeof allyConfig> {} | ||
} |
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,19 @@ | ||
import { cn } from '@/lib/utils' | ||
import { TWColor } from '@/types/utils' | ||
|
||
interface DividerProps { | ||
text: string | ||
color?: TWColor | ||
} | ||
|
||
function Divider({ text, color = 'gray-500' }: DividerProps) { | ||
return ( | ||
<div className={cn('flex flex-row items-center gap-4', `color-${color}`)}> | ||
<hr className="flex flex-grow" /> | ||
<small className={cn('uppercase', `text-${color}`)}>{text}</small> | ||
<hr className="flex flex-grow" /> | ||
</div> | ||
) | ||
} | ||
|
||
export default Divider |
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,63 @@ | ||
import Divider from '@/components/generic/divider' | ||
import { Button } from '@/components/ui/button' | ||
import { route } from '@izzyjs/route/client' | ||
import { Chrome, Github } from 'lucide-react' | ||
import { useState } from 'react' | ||
|
||
interface SocialButtonsProps { | ||
disabled?: boolean | ||
} | ||
|
||
const SOCIALS = [ | ||
{ | ||
provider: 'Google', | ||
Icon: Chrome, | ||
enabled: false, | ||
}, | ||
{ | ||
provider: 'GitHub', | ||
Icon: Github, | ||
enabled: true, | ||
}, | ||
] as const | ||
|
||
function SocialButtons({ disabled = false }: SocialButtonsProps) { | ||
const [processing, setProcessing] = useState<'Google' | 'GitHub' | null>(null) | ||
return ( | ||
<> | ||
<Divider text="with socials" color="gray-500" /> | ||
{SOCIALS.map(({ provider, Icon, enabled }) => { | ||
const providerLC = provider.toLowerCase() | ||
return ( | ||
<Button | ||
key={`auth-${providerLC}`} | ||
type="button" | ||
className="w-full" | ||
variant="outline" | ||
disabled={!enabled || processing === provider || disabled} | ||
loading={processing === provider} | ||
> | ||
<a | ||
className="flex flex-row items-center gap-2" | ||
href={ | ||
enabled | ||
? route('auth.redirect', { | ||
params: { | ||
provider: providerLC, | ||
}, | ||
}).path | ||
: '#' | ||
} | ||
onClick={() => setProcessing(provider)} | ||
> | ||
<Icon size={16} /> | ||
{provider} | ||
</a> | ||
</Button> | ||
) | ||
})} | ||
</> | ||
) | ||
} | ||
|
||
export default SocialButtons |
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
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 type { DefaultColors } from '../../node_modules/tailwindcss/types/generated/colors' | ||
|
||
type TWColorDefaults = 'inherit' | 'current' | 'transparent' | 'black' | 'white' | ||
type TWColorKey = keyof Omit<DefaultColors, TWColorDefaults> | ||
type TWColorTone = keyof DefaultColors[TWColorKey] | ||
export type TWColor = `${TWColorKey}-${TWColorTone}` | TWColorDefaults |
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.