feat: registration provider
This commit is contained in:
parent
3551516877
commit
86e71c0d90
|
|
@ -5,7 +5,7 @@ export class GithubProvider implements ProvidersInterface {
|
|||
return `https://github.com/login/oauth/authorize?client_id=${
|
||||
process.env.GITHUB_CLIENT_ID
|
||||
}&scope=user:email&redirect_uri=${encodeURIComponent(
|
||||
`${process.env.FRONTEND_URL}/settings?provider=github`
|
||||
`${process.env.FRONTEND_URL}/settings`
|
||||
)}`;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
import {
|
||||
AnalyticsData,
|
||||
AuthTokenDetails,
|
||||
PostDetails,
|
||||
PostResponse,
|
||||
SocialProvider,
|
||||
} from '@gitroom/nestjs-libraries/integrations/social/social.integrations.interface';
|
||||
import { makeId } from '@gitroom/nestjs-libraries/services/make.is';
|
||||
import { google } from 'googleapis';
|
||||
import { OAuth2Client } from 'google-auth-library/build/src/auth/oauth2client';
|
||||
import { ProvidersInterface } from '@gitroom/backend/services/auth/providers.interface';
|
||||
|
||||
const clientAndYoutube = () => {
|
||||
const client = new google.auth.OAuth2({
|
||||
clientId: process.env.YOUTUBE_CLIENT_ID,
|
||||
clientSecret: process.env.YOUTUBE_CLIENT_SECRET,
|
||||
redirectUri: `${process.env.FRONTEND_URL}/integrations/social/youtube`,
|
||||
});
|
||||
|
||||
const youtube = (newClient: OAuth2Client) =>
|
||||
google.youtube({
|
||||
version: 'v3',
|
||||
auth: newClient,
|
||||
});
|
||||
|
||||
const youtubeAnalytics = (newClient: OAuth2Client) =>
|
||||
google.youtubeAnalytics({
|
||||
version: 'v2',
|
||||
auth: newClient,
|
||||
});
|
||||
|
||||
const oauth2 = (newClient: OAuth2Client) =>
|
||||
google.oauth2({
|
||||
version: 'v2',
|
||||
auth: newClient,
|
||||
});
|
||||
|
||||
return { client, youtube, oauth2, youtubeAnalytics };
|
||||
};
|
||||
|
||||
export class GoogleProvider implements ProvidersInterface {
|
||||
generateLink() {
|
||||
const state = makeId(7);
|
||||
const { client } = clientAndYoutube();
|
||||
return client.generateAuthUrl({
|
||||
access_type: 'online',
|
||||
prompt: 'consent',
|
||||
state,
|
||||
redirect_uri: `${process.env.FRONTEND_URL}/integrations/social/youtube`,
|
||||
scope: [
|
||||
'https://www.googleapis.com/auth/userinfo.profile',
|
||||
'https://www.googleapis.com/auth/userinfo.email',
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
async getToken(code: string) {
|
||||
const { client, oauth2 } = clientAndYoutube();
|
||||
const { tokens } = await client.getToken(code);
|
||||
return tokens.access_token;
|
||||
}
|
||||
|
||||
async getUser(providerToken: string) {
|
||||
const { client, oauth2 } = clientAndYoutube();
|
||||
client.setCredentials({ access_token: providerToken });
|
||||
const user = oauth2(client);
|
||||
const { data } = await user.userinfo.get();
|
||||
|
||||
return {
|
||||
id: data.id!,
|
||||
email: data.email,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,15 @@
|
|||
import {Provider} from "@prisma/client";
|
||||
import {GithubProvider} from "@gitroom/backend/services/auth/providers/github.provider";
|
||||
import {ProvidersInterface} from "@gitroom/backend/services/auth/providers.interface";
|
||||
import { Provider } from '@prisma/client';
|
||||
import { GithubProvider } from '@gitroom/backend/services/auth/providers/github.provider';
|
||||
import { ProvidersInterface } from '@gitroom/backend/services/auth/providers.interface';
|
||||
import { GoogleProvider } from '@gitroom/backend/services/auth/providers/google.provider';
|
||||
|
||||
export class ProvidersFactory {
|
||||
static loadProvider(provider: Provider): ProvidersInterface {
|
||||
switch (provider) {
|
||||
case Provider.GITHUB:
|
||||
return new GithubProvider();
|
||||
}
|
||||
static loadProvider(provider: Provider): ProvidersInterface {
|
||||
switch (provider) {
|
||||
case Provider.GITHUB:
|
||||
return new GithubProvider();
|
||||
case Provider.GOOGLE:
|
||||
return new GoogleProvider();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { Input } from '@gitroom/react/form/input';
|
|||
import { useMemo, useState } from 'react';
|
||||
import { classValidatorResolver } from '@hookform/resolvers/class-validator';
|
||||
import { LoginUserDto } from '@gitroom/nestjs-libraries/dtos/auth/login.user.dto';
|
||||
import { GithubProvider } from '@gitroom/frontend/app/auth/providers/github.provider';
|
||||
import { GithubProvider } from '@gitroom/frontend/components/auth/providers/github.provider';
|
||||
import interClass from '@gitroom/react/helpers/inter.font';
|
||||
import { isGeneral } from '@gitroom/react/helpers/is.general';
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
import { useCallback } from 'react';
|
||||
import { useFetch } from '@gitroom/helpers/utils/custom.fetch';
|
||||
import interClass from '@gitroom/react/helpers/inter.font';
|
||||
|
||||
export const GoogleProvider = () => {
|
||||
const fetch = useFetch();
|
||||
const gotoLogin = useCallback(async () => {
|
||||
const link = await (await fetch('/auth/oauth/GOOGLE')).text();
|
||||
window.location.href = link;
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
onClick={gotoLogin}
|
||||
className={`cursor-pointer bg-white h-[44px] rounded-[4px] flex justify-center items-center text-[#121A2D] ${interClass} gap-[4px]`}
|
||||
>
|
||||
<div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 48 48"
|
||||
width="21px"
|
||||
height="21px"
|
||||
>
|
||||
<path
|
||||
fill="#FFC107"
|
||||
d="M43.611,20.083H42V20H24v8h11.303c-1.649,4.657-6.08,8-11.303,8c-6.627,0-12-5.373-12-12c0-6.627,5.373-12,12-12c3.059,0,5.842,1.154,7.961,3.039l5.657-5.657C34.046,6.053,29.268,4,24,4C12.955,4,4,12.955,4,24c0,11.045,8.955,20,20,20c11.045,0,20-8.955,20-20C44,22.659,43.862,21.35,43.611,20.083z"
|
||||
/>
|
||||
<path
|
||||
fill="#FF3D00"
|
||||
d="M6.306,14.691l6.571,4.819C14.655,15.108,18.961,12,24,12c3.059,0,5.842,1.154,7.961,3.039l5.657-5.657C34.046,6.053,29.268,4,24,4C16.318,4,9.656,8.337,6.306,14.691z"
|
||||
/>
|
||||
<path
|
||||
fill="#4CAF50"
|
||||
d="M24,44c5.166,0,9.86-1.977,13.409-5.192l-6.19-5.238C29.211,35.091,26.715,36,24,36c-5.202,0-9.619-3.317-11.283-7.946l-6.522,5.025C9.505,39.556,16.227,44,24,44z"
|
||||
/>
|
||||
<path
|
||||
fill="#1976D2"
|
||||
d="M43.611,20.083H42V20H24v8h11.303c-0.792,2.237-2.231,4.166-4.087,5.571c0.001-0.001,0.002-0.001,0.003-0.002l6.19,5.238C36.971,39.205,44,34,44,24C44,22.659,43.862,21.35,43.611,20.083z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>Sign in with Google</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
@ -8,12 +8,13 @@ import { Input } from '@gitroom/react/form/input';
|
|||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { classValidatorResolver } from '@hookform/resolvers/class-validator';
|
||||
import { CreateOrgUserDto } from '@gitroom/nestjs-libraries/dtos/auth/create.org.user.dto';
|
||||
import { GithubProvider } from '@gitroom/frontend/app/auth/providers/github.provider';
|
||||
import { GithubProvider } from '@gitroom/frontend/components/auth/providers/github.provider';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import { LoadingComponent } from '@gitroom/frontend/components/layout/loading';
|
||||
import interClass from '@gitroom/react/helpers/inter.font';
|
||||
import { isGeneral } from '@gitroom/react/helpers/is.general';
|
||||
import clsx from 'clsx';
|
||||
import { GoogleProvider } from '@gitroom/frontend/components/auth/providers/google.provider';
|
||||
|
||||
type Inputs = {
|
||||
email: string;
|
||||
|
|
@ -125,8 +126,8 @@ export function RegisterAfter({
|
|||
Sign Up
|
||||
</h1>
|
||||
</div>
|
||||
{!isAfterProvider && !isGeneral() && <GithubProvider />}
|
||||
{!isAfterProvider && !isGeneral() && (
|
||||
{!isAfterProvider && (!isGeneral() ? <GithubProvider /> : <GoogleProvider />)}
|
||||
{!isAfterProvider && (
|
||||
<div className="h-[20px] mb-[24px] mt-[24px] relative">
|
||||
<div className="absolute w-full h-[1px] bg-[#28344F] top-[50%] -translate-y-[50%]" />
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -30,7 +30,10 @@ export async function middleware(request: NextRequest) {
|
|||
const url = new URL(nextUrl).search;
|
||||
|
||||
if (nextUrl.href.indexOf('/auth') === -1 && !authCookie) {
|
||||
return NextResponse.redirect(new URL(`/auth${url}`, nextUrl.href));
|
||||
const providers = ['google', 'github'];
|
||||
const findIndex = providers.find(p => nextUrl.href.indexOf(p) > -1);
|
||||
const additional = !findIndex ? '' : (url.indexOf('?') > -1 ? '&' : '?') + `provider=${findIndex.toUpperCase()}`;
|
||||
return NextResponse.redirect(new URL(`/auth${url}${additional}`, nextUrl.href));
|
||||
}
|
||||
|
||||
// If the url is /auth and the cookie exists, redirect to /
|
||||
|
|
|
|||
|
|
@ -413,6 +413,7 @@ enum Period {
|
|||
enum Provider {
|
||||
LOCAL
|
||||
GITHUB
|
||||
GOOGLE
|
||||
}
|
||||
|
||||
enum Role {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export class EmailService {
|
|||
return;
|
||||
}
|
||||
await resend.emails.send({
|
||||
from: 'Gitroom <no-reply@gitroom.com>',
|
||||
from: process.env.IS_GENERAL === 'true' ? 'Nevo <nevo@postiz.com>' : 'Nevo <nevo@gitroom.com>',
|
||||
to,
|
||||
subject,
|
||||
html,
|
||||
|
|
|
|||
Loading…
Reference in New Issue