Skip to content

Github SSO #191

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions packages/frontendmu-nuxt/auth-utils/useAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export default function useAuth(client: DirectusClient<any> & AuthenticationClie
credentials: 'include', // this is required in order to send the refresh token cookie
body: JSON.stringify({
refresh_token: getCookieValue('directus_session_token'),
mode: 'cookie',
}),
},
)
Expand Down Expand Up @@ -171,10 +172,12 @@ export default function useAuth(client: DirectusClient<any> & AuthenticationClie
'meal',
'occupation',
'github_username',
'external_identifier',
'Events.Events_id.id',
'Events.Events_id.title',
'profile_picture',
'role.name',
'provider',
]

try {
Expand Down Expand Up @@ -220,9 +223,23 @@ export default function useAuth(client: DirectusClient<any> & AuthenticationClie
return false
})

function oAuthLogin() {
const currentPage = new URL(window.location.origin)
return `${DIRECTUS_URL()}/auth/login/google?redirect=${currentPage}redirect`
function oAuthLogin(provider: string) {
if (provider === 'google') {
const currentPage = new URL(window.location.origin)
return `${DIRECTUS_URL()}/auth/login/google?redirect=${currentPage}redirect`
}
else if (provider === 'github') {
const currentPage = new URL(window.location.origin)
return `${DIRECTUS_URL()}/auth/login/github?redirect=${currentPage}redirect`
}
else if (provider === 'discord') {
const currentPage = new URL(window.location.origin)
return `${DIRECTUS_URL()}/auth/login/discord?redirect=${currentPage}redirect`
}

console.log('Provider not found')

return false
}

async function updateUserProfile({ profile_updates }: { profile_updates: DirectusAstroUser }) {
Expand Down
71 changes: 58 additions & 13 deletions packages/frontendmu-nuxt/components/auth/LoggedUser.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,74 @@ onMounted(() => {
<template>
<div class="dark:text-zinc-200 dark:ring-white/10 pl-4">
<BaseButton
v-if="!isLoggedIn" href="/login" color="primary" class="font-medium hidden md:block"
v-if="!isLoggedIn"
href="/login"
color="primary"
class="font-medium hidden md:block"
@click="setUrl()"
>
Log In
</BaseButton>
<BaseButton
v-if="!isLoggedIn" href="/login" color="primary" class="font-medium block md:hidden" size="sm"
v-if="!isLoggedIn"
href="/login"
color="primary"
class="font-medium block md:hidden"
size="sm"
@click="setUrl()"
>
Log In
</BaseButton>
<div v-else class="flex gap-2 items-center">
<Menu as="div" class="relative inline-block text-left">
<div
v-else
class="flex gap-2 items-center"
>
<Menu
as="div"
class="relative inline-block text-left"
>
<div>
<MenuButton
class="inline-flex items-center w-full justify-center gap-x-1.5 rounded-full text-sm font-semibold text-verse-900 dark:text-verse-100 shadow-sm ring-gray-300 hover:bg-gray-50"
class="inline-flex relative items-center w-full justify-center gap-x-1.5 rounded-full text-sm font-semibold text-verse-900 dark:text-verse-100 shadow-sm ring-gray-300 hover:bg-gray-50"
>
<div v-if="avatarUrl">
<img class="w-10 aspect-square rounded-full" :src="avatarUrl">
<template v-if="user?.provider === 'github'">
<img
class="w-10 aspect-square rounded-full"
:src="`https://github.com/${user?.external_identifier}.png`"
>
</template>
<template v-else>
<div v-if="avatarUrl">
<img
class="w-10 aspect-square rounded-full"
:src="avatarUrl"
>
</div>
</template>
<!-- Provider Hint -->
<div class="absolute bottom-0 right-0 bg-white rounded-full">
<div v-if="user?.provider === 'default'">
<Icon
class="block w-3 h-3 p-0.5 text-black"
name="fluent:animal-rabbit-24-regular"
/>
</div>
<div v-else>
<Icon
:name="`carbon:logo-${user?.provider}`"
class="block w-3 h-3 p-0.5 text-black"
/>
</div>
</div>
<!-- <ChevronDownIcon class="-mr-1 h-5 w-5 text-gray-400" aria-hidden="true" /> -->
</MenuButton>
</div>

<transition
enter-active-class="transition ease-out duration-100"
enter-from-class="transform opacity-0 scale-95" enter-to-class="transform opacity-100 scale-100"
leave-active-class="transition ease-in duration-75" leave-from-class="transform opacity-100 scale-100"
enter-from-class="transform opacity-0 scale-95"
enter-to-class="transform opacity-100 scale-100"
leave-active-class="transition ease-in duration-75"
leave-from-class="transform opacity-100 scale-100"
leave-to-class="transform opacity-0 scale-95"
>
<MenuItems
Expand All @@ -53,15 +93,17 @@ onMounted(() => {
<MenuItem v-slot="{ active }">
<NuxtLink
href="/user/me"
class="block px-4 py-2 text-sm" :class="[active ? 'bg-gray-400/10 text-verse-900 dark:text-verse-100' : 'text-verse-900 dark:text-verse-100']"
class="block px-4 py-2 text-sm"
:class="[active ? 'bg-gray-400/10 text-verse-900 dark:text-verse-100' : 'text-verse-900 dark:text-verse-100']"
>
My
Profile
</NuxtLink>
</MenuItem>
<MenuItem v-slot="{ active }">
<NuxtLink
class="block px-4 py-2 text-sm cursor-pointer" :class="[active ? 'bg-gray-400/10 text-verse-900 dark:text-verse-100' : 'text-verse-900 dark:text-verse-100']"
class="block px-4 py-2 text-sm cursor-pointer"
:class="[active ? 'bg-gray-400/10 text-verse-900 dark:text-verse-100' : 'text-verse-900 dark:text-verse-100']"
@click="logout()"
>
Logout
Expand All @@ -71,7 +113,10 @@ onMounted(() => {
<div class="text-verse-900 dark:text-verse-100 p-4 text-sm">
<div class="flex flex-col items-center justify-center gap-2">
<div v-if="avatarUrl">
<img class="w-16 aspect-square rounded-full" :src="avatarUrl">
<img
class="w-16 aspect-square rounded-full"
:src="avatarUrl"
>
</div>

{{ user?.full_name }}
Expand Down
63 changes: 51 additions & 12 deletions packages/frontendmu-nuxt/components/auth/LoginForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,36 @@ const developmentEnvironment = process.env.NODE_ENV === 'development'

<template>
<div class="sm:mx-auto sm:w-full sm:max-w-md">
<MiscLogoFec class="w-10 mx-auto dark:text-white" :loading="isLoading" />
<MiscLogoFec
class="w-10 mx-auto dark:text-white"
:loading="isLoading"
/>
<h2 class="mt-6 text-center text-2xl font-bold leading-9 tracking-tight text-verse-900 dark:text-verse-100">
{{ isLoggedIn ? 'Welcome back' : 'Sign in to your account' }}
</h2>
</div>
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-[480px] flex justify-center">
<div class="bg-verse-200/10 overflow-hidden dark:bg-verse-500/20 backdrop-blur-sm px-6 py-12 shadow-2xl rounded-lg sm:px-12 w-11/12">
<div
class="bg-verse-200/10 overflow-hidden dark:bg-verse-500/20 backdrop-blur-sm px-6 py-12 shadow-2xl rounded-lg sm:px-12 w-11/12"
>
<div v-if="isLoggedIn">
<div class="text-center flex flex-col gap-8 text-verse-900 dark:text-verse-100 w-full">
<span>
You are logged in as <NuxtLink class="underline" href="/user/me"> {{ user?.full_name }}
You are logged in as <NuxtLink
class="underline"
href="/user/me"
> {{ user?.full_name }}
</NuxtLink>
</span>
<div v-if="willRedirect">
redirecting in {{ Math.round(countdown / 1000) }}s
</div>

<div class="grid grid-cols-2 gap-4 w-full justify-evenly">
<BaseButton color="neutral" @click="logout">
<BaseButton
color="neutral"
@click="logout"
>
Logout
</BaseButton>
<BaseButton href="/user/me">
Expand All @@ -50,7 +61,11 @@ const developmentEnvironment = process.env.NODE_ENV === 'development'
</div>
</div>
<div v-else>
<form v-if="developmentEnvironment" class="space-y-6" @submit.prevent="login()">
<form
v-if="developmentEnvironment"
class="space-y-6"
@submit.prevent="login()"
>
<div>
<label
for="email"
Expand Down Expand Up @@ -84,7 +99,8 @@ const developmentEnvironment = process.env.NODE_ENV === 'development'
v-model="password"
name="password"
type="password"
autocomplete="current-password" required
autocomplete="current-password"
required
class="block w-full rounded-md border-0 p-1.5 text-verse-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-verse-600 sm:text-sm sm:leading-6"
>
</div>
Expand Down Expand Up @@ -118,26 +134,37 @@ const developmentEnvironment = process.env.NODE_ENV === 'development'
</div>

<div class="relative">
<div class="absolute inset-0 flex items-center" aria-hidden="true">
<div
class="absolute inset-0 flex items-center"
aria-hidden="true"
>
<div class="w-full border-t border-verse-500/20" />
</div>
</div>

<div class="mt-10 grid sm:grid-cols-2 gap-4">
<a
:href="oAuthLogin()"
:href="oAuthLogin('google')"
class="flex w-full items-center justify-center gap-3 rounded-md bg-[#000000] hover:bg-black/50 transition-all duration-300 px-3 py-1.5 text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#1D9BF0]"
>
<Icon name="logos:google-icon" class="h-5 w-5" />
<Icon
name="logos:google-icon"
class="h-5 w-5"
/>
<span class="text-sm font-semibold leading-6">Google</span>
</a>

<a
href="#"
class="opacity-60 cursor-not-allowed flex w-full items-center justify-center gap-3 rounded-md bg-[#24292F] px-3 py-1.5 text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#24292F]"
:href="oAuthLogin('github')"
class="flex w-full items-center justify-center gap-3 rounded-md bg-[#000000] hover:bg-black/50 px-3 py-1.5 text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#24292F]"
disabled
>
<svg class="h-5 w-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<svg
class="h-5 w-5"
aria-hidden="true"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fill-rule="evenodd"
d="M10 0C4.477 0 0 4.484 0 10.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0110 4.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.203 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.942.359.31.678.921.678 1.856 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0020 10.017C20 4.484 15.522 0 10 0z"
Expand All @@ -146,6 +173,18 @@ const developmentEnvironment = process.env.NODE_ENV === 'development'
</svg>
<span class="text-sm font-semibold leading-6">GitHub</span>
</a>

<!-- <a
:href="oAuthLogin('discord')"
class="flex w-full items-center justify-center gap-3 rounded-md bg-[#000000] hover:bg-black/50 px-3 py-1.5 text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#24292F]"
disabled
>
<Icon
name="logos:discord-icon"
class="h-5 w-5"
/>
<span class="text-sm font-semibold leading-6">Discord</span>
</a> -->
</div>
</div>
</div>
Expand Down
Loading
Loading