feat: create token with oauth

This commit is contained in:
EnixCoda 2019-08-24 17:56:14 +08:00
parent bd5409d277
commit ed821c7959
No known key found for this signature in database
GPG key ID: 0C1A07377913A1DD
3 changed files with 74 additions and 1 deletions

View file

@ -0,0 +1,5 @@
# The client ID you received from GitHub for your GitHub App.
GITHUB_OAUTH_CLIENT_ID=GITHUB_OAUTH_CLIENT_ID
# The client secret you received from GitHub for your GitHub App.
GITHUB_OAUTH_CLIENT_SECRET=GITHUB_OAUTH_CLIENT_SECRET

View file

@ -2,7 +2,7 @@ import * as React from 'react'
import Icon from 'components/Icon'
import configHelper, { configKeys } from 'utils/configHelper'
import keyHelper from 'utils/keyHelper'
import { friendlyFormatShortcut } from 'utils/general'
import { friendlyFormatShortcut, parseURLSearch, JSONRequest } from 'utils/general'
import { version } from '../../package.json'
const wikiLinks = {
@ -14,6 +14,11 @@ const wikiLinks = {
'https://github.com/EnixCoda/Gitako/wiki/How-to-create-access-token-for-Gitako%3F',
}
const oauth = {
clientId: process.env.GITHUB_OAUTH_CLIENT_ID,
clientSecret: process.env.GITHUB_OAUTH_CLIENT_SECRET,
}
const ACCESS_TOKEN_REGEXP = /^[0-9a-f]{40}$/
type Props = {
@ -84,12 +89,33 @@ export default class SettingsBar extends React.PureComponent<Props, State> {
],
}
componentDidMount() {
if (!this.props.accessToken) this.trySetUpAccessTokenWithCode()
}
componentWillReceiveProps({ toggleShowSideBarShortcut }: Props) {
if (toggleShowSideBarShortcut !== this.props.toggleShowSideBarShortcut) {
this.setState({ toggleShowSideBarShortcut })
}
}
private async trySetUpAccessTokenWithCode() {
const search = parseURLSearch()
if ('code' in search) {
const res = await JSONRequest('https://github.com/login/oauth/access_token', {
code: search.code,
client_id: oauth.clientId,
client_secret: oauth.clientSecret,
})
const { access_token: accessToken, scope } = res
if (scope !== 'repo' || !accessToken) {
throw new Error(`Cannot resolve token response: '${JSON.stringify(res)}'`)
}
window.history.pushState({}, 'removed code', window.location.pathname.replace(/#.*$/, ''))
this.setState({ accessToken }, () => this.saveToken())
}
}
onInputAccessToken = (event: React.FormEvent<HTMLInputElement>) => {
const { value } = event.currentTarget
this.setState({
@ -197,6 +223,13 @@ export default class SettingsBar extends React.PureComponent<Props, State> {
<div className={'shadow-shelter'} />
<div className={'gitako-settings-bar-content-section access-token'}>
<h4>Access Token</h4>
<a
href={`https://github.com/login/oauth/authorize?client_id=${
oauth.clientId
}&scope=repo&redirect_uri=${encodeURIComponent(window.location.href)}`}
>
Create token
</a>
<a href={wikiLinks.createAccessToken} target="_blank">
Why & how to create it?
</a>

View file

@ -93,3 +93,38 @@ export function createStyleSheet(content: string) {
export function setStyleSheetMedia(style: HTMLStyleElement, media: string) {
style.setAttribute('media', media)
}
export function parseURLSearch(search: string = window.location.search) {
const parsed: any = {}
if (search.startsWith('?')) {
const pairs = search
.slice(1)
.split('&')
.map(rawPair => rawPair.split('=').map(raw => decodeURIComponent(raw))) // [key, value?][]
pairs.forEach(([key, value]) => {
if (Object.prototype.hasOwnProperty.call(parsed, key)) {
if (Array.isArray(parsed[key])) parsed[key].push(value)
else parsed[key] = [parsed[key], value]
} else {
parsed[key] = value
}
})
}
return parsed
}
export async function JSONRequest(url: string, data: any, method = 'post') {
return (await fetch(url, {
method,
mode: 'cors',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
redirect: 'follow',
referrer: 'no-referrer',
body: JSON.stringify(data),
})).json()
}