mirror of
https://github.com/Aviortheking/CA_Cyber_Security.git
synced 2025-08-11 20:31:59 +00:00
66
src/libs/GoogleClient.ts
Normal file
66
src/libs/GoogleClient.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import URLManager from '@dzeio/url-manager'
|
||||
|
||||
interface userInformations {
|
||||
family_name: string
|
||||
name: string
|
||||
picture: string
|
||||
locale: string
|
||||
email: string
|
||||
given_name: string
|
||||
id: string
|
||||
verified_email: boolean
|
||||
}
|
||||
|
||||
export default class GoogleClient {
|
||||
|
||||
public static config = {
|
||||
clientID: process.env.GOOGLE_CLIENT_ID || '',
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET || '',
|
||||
redirectURI: process.env.GOOGLE_REDIRECT || ''
|
||||
}
|
||||
|
||||
public static scopes = [
|
||||
'email',
|
||||
'https://www.googleapis.com/auth/userinfo.profile'
|
||||
]
|
||||
|
||||
|
||||
public static getUrl(): string {
|
||||
return new URLManager('https://accounts.google.com/o/oauth2/v2/auth')
|
||||
.query('client_id', this.config.clientID || '')
|
||||
.query('redirect_uri', this.config.redirectURI || '')
|
||||
.query('response_type', 'code')
|
||||
.query('scope', this.scopes.join(encodeURI(' ')))
|
||||
.toString()
|
||||
}
|
||||
|
||||
public static async processCode(code: string): Promise<{id: string, email: string}> {
|
||||
// Fetch Access Token
|
||||
const url1 = new URLManager()
|
||||
.query('code', code)
|
||||
.query('redirect_uri', encodeURI(this.config.redirectURI))
|
||||
.query('client_id', this.config.clientID)
|
||||
.query('client_secret', this.config.clientSecret)
|
||||
.query('grant_type', 'authorization_code')
|
||||
|
||||
const { access_token }: {access_token: string} = await fetch('https://oauth2.googleapis.com/token', {
|
||||
body: url1.toString().substr(1),
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
}).then((resp) => resp.json())
|
||||
|
||||
// Fetch informations
|
||||
const { id, email }: userInformations = await fetch('https://www.googleapis.com/userinfo/v2/me', {
|
||||
headers: {
|
||||
Authorization: `Bearer ${access_token}`
|
||||
}
|
||||
}).then((resp) => resp.json())
|
||||
|
||||
return {
|
||||
id,
|
||||
email
|
||||
}
|
||||
}
|
||||
}
|
13
src/pages/_app.tsx
Normal file
13
src/pages/_app.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import App from 'next/app'
|
||||
import React from 'react'
|
||||
|
||||
import './general.styl'
|
||||
|
||||
export default class Application extends App {
|
||||
|
||||
public render() {
|
||||
const { Component, pageProps } = this.props
|
||||
|
||||
return <Component {...pageProps} />
|
||||
}
|
||||
}
|
6
src/pages/general.styl
Normal file
6
src/pages/general.styl
Normal file
@@ -0,0 +1,6 @@
|
||||
*
|
||||
box-sizing border-box
|
||||
|
||||
html
|
||||
body
|
||||
margin 0
|
32
src/pages/index.tsx
Normal file
32
src/pages/index.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import { GetServerSideProps } from 'next'
|
||||
import React from 'react'
|
||||
import Image from 'next/image'
|
||||
import Router from 'next/router'
|
||||
import GoogleClient from '../libs/GoogleClient'
|
||||
import css from './style.module.styl'
|
||||
|
||||
interface Props {
|
||||
oauth: string
|
||||
}
|
||||
|
||||
export default class Index extends React.Component<Props> {
|
||||
public render = () => (
|
||||
<div className={css.parent}>
|
||||
<div className={css.boxWrapper}>
|
||||
<Image src="/google.svg" width={75} height={24} />
|
||||
<p className={css.title}>Connexion</p>
|
||||
<p className={css.txt}>Utiliser votre compote Google</p>
|
||||
<i className={css.sub}>S'il ne s'agit pas de votre ordinateur, blablabla, En savoir plus</i>
|
||||
<a className={css.button} href={this.props.oauth}>Google</a>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps<Props> = async (ctx) => {
|
||||
return {
|
||||
props: {
|
||||
oauth: GoogleClient.getUrl()
|
||||
}
|
||||
}
|
||||
}
|
57
src/pages/informations.tsx
Normal file
57
src/pages/informations.tsx
Normal file
@@ -0,0 +1,57 @@
|
||||
import { GetServerSideProps } from 'next'
|
||||
import React from 'react'
|
||||
import Image from 'next/image'
|
||||
import Router from 'next/router'
|
||||
import GoogleClient from '../libs/GoogleClient'
|
||||
import css from './style.module.styl'
|
||||
import URLManager from '@dzeio/url-manager'
|
||||
|
||||
interface Props {
|
||||
code: string
|
||||
email: string
|
||||
id: string
|
||||
}
|
||||
|
||||
export default class Index extends React.Component<Props> {
|
||||
public render = () => (
|
||||
<div className={css.parent}>
|
||||
<div className={css.boxWrapper}>
|
||||
<Image src="/google.svg" width={75} height={24} />
|
||||
<p className={css.txt}>Code: {this.props.code}</p>
|
||||
<p className={css.txt}>Email: {this.props.email}</p>
|
||||
<i className={css.txt}>Id: {this.props.id}</i>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps<Props> = async (ctx) => {
|
||||
const { code } = ctx.query as { code: string }
|
||||
try {
|
||||
const infos = await GoogleClient.processCode(code)
|
||||
if (!infos.email || !infos.id) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: '/',
|
||||
statusCode: 301
|
||||
},
|
||||
}
|
||||
}
|
||||
return {
|
||||
props: {
|
||||
code,
|
||||
email: infos.email,
|
||||
id: infos.id
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
return {
|
||||
redirect: {
|
||||
destination: '/',
|
||||
statusCode: 301
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
}
|
40
src/pages/style.module.styl
Normal file
40
src/pages/style.module.styl
Normal file
@@ -0,0 +1,40 @@
|
||||
.button
|
||||
background #1973E8
|
||||
color white
|
||||
text-decoration none
|
||||
padding 8px 16px
|
||||
border-radius 8px
|
||||
font-family sans-serif
|
||||
display inline-block
|
||||
|
||||
.boxWrapper
|
||||
margin auto
|
||||
padding 16px
|
||||
border 1px solid #DADCE0
|
||||
border-radius 16px
|
||||
display inline-block
|
||||
text-align center
|
||||
|
||||
.parent
|
||||
display flex
|
||||
align-content center
|
||||
justify-content center
|
||||
height 100vh
|
||||
|
||||
.title
|
||||
font-size 1.3rem
|
||||
font-family sans-serif
|
||||
font-weight bold
|
||||
margin-bottom 8px
|
||||
|
||||
.txt
|
||||
font-family sans-serif
|
||||
font-size 1rem
|
||||
margin 0
|
||||
|
||||
.sub
|
||||
font-family sans-serif
|
||||
font-size .8rem
|
||||
margin 8px 0
|
||||
|
||||
display block
|
Reference in New Issue
Block a user