Skip to content

Commit a88632e

Browse files
kakao-joo-yoonjoostory
authored andcommitted
구글 포토 인증 ExternalOAuth2로 전환
1 parent 894b762 commit a88632e

File tree

6 files changed

+114
-113
lines changed

6 files changed

+114
-113
lines changed

src/main/apis/photos-api.js

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
const oauth2 = require('../oauth/ElectronOauth2');
2+
const ExternalOAuth2 = require('../oauth/ExternalOAuth2')
23
const fetch = require('isomorphic-fetch')
34
const {clipboard, session} = require('electron')
45
const OauthInfoReader = require('../oauth/OauthInfoReader')
5-
const appInfo = require('../appInfo')
6+
const appInfo = require('../appInfo');
7+
const OAuthRequestManager = require('../oauth/OAuthRequestManager');
68

79
class GoogleAuthApi {
10+
#googleOAuth
11+
812
constructor() {
9-
this.googleOAuth = null
13+
this.#googleOAuth = null
1014
}
1115

1216
makeGoogleOAuth() {
13-
if (!this.googleOAuth) {
17+
if (!this.#googleOAuth) {
1418
const oauthInfoReader = new OauthInfoReader()
1519
const oauthInfo = oauthInfoReader.getGoogle()
1620

17-
this.googleOAuth = oauth2(oauthInfo, {
21+
this.#googleOAuth = oauth2(oauthInfo, {
1822
alwaysOnTop: true,
1923
autoHideMenuBar: true,
2024
webPreferences: {
@@ -25,9 +29,31 @@ class GoogleAuthApi {
2529
})
2630
}
2731

28-
return this.googleOAuth
32+
return this.#googleOAuth
2933
}
3034

35+
requestAuth(successHandler, failureHandler) {
36+
const oauthInfoReader = new OauthInfoReader()
37+
const oauth2 = new ExternalOAuth2(oauthInfoReader.getGoogle())
38+
OAuthRequestManager.saveRequestInfo("oauth", (searchParams) => {
39+
const code = searchParams.get("code")
40+
oauth2.requestToken(code)
41+
.then(data => {
42+
if (data.error) {
43+
throw new Error(`${data.error}: ${data.error_description}`)
44+
}
45+
46+
return data
47+
})
48+
.then(successHandler)
49+
.catch(failureHandler)
50+
})
51+
52+
oauth2.requestAuth({
53+
scope: ['https://www.googleapis.com/auth/photoslibrary.readonly']
54+
})
55+
}
56+
3157
getAccessToken() {
3258
return this.makeGoogleOAuth().getAccessToken({
3359
scope: ['https://www.googleapis.com/auth/photoslibrary.readonly']

src/main/events/google-photos.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module.exports = () => {
66
const authApi = new GoogleAuthApi()
77
const fetchImages = async (evt, nextPageToken) => {
88
console.log('fetchImage', nextPageToken)
9-
const auth = settings.get('google-auth')
9+
const auth = settings.getSync('google-auth')
1010

1111
try {
1212
if (!auth || !auth.access_token) {
@@ -32,7 +32,7 @@ module.exports = () => {
3232
} else {
3333
evt.sender.send('receive-google-connected', false)
3434
}
35-
evt.sender.send('receive-google-photos-images', [])
35+
evt.sender.send('receive-google-photos-images', null)
3636
}
3737
}
3838

@@ -43,11 +43,14 @@ module.exports = () => {
4343

4444
ipcMain.on("request-google-photos-auth", (evt, arg) => {
4545
console.log('Main.receive: request-google-photos-auth')
46-
authApi.getAccessToken().then(auth => {
47-
settings.setSync('google-auth', auth)
46+
authApi.requestAuth((auth) => {
47+
settings.setSync('google-auth', auth)
4848
evt.sender.send('receive-google-connected', true)
49-
fetchImages(evt, null)
50-
})
49+
fetchImages(evt, null)//
50+
}, () => {
51+
console.error(e)
52+
evt.sender.send('receive-message', `오류가 발생했습니다. (${e.message})`)
53+
})
5154
})
5255

5356
ipcMain.on("disconnect-google-photos-auth", (evt, arg) => {

src/main/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ app.on('window-all-closed', () => {
2525
})
2626

2727
app.on("open-url", (e, urlString) => {
28+
console.log("OPEN-URL", urlString)
2829
const url = new URL(urlString)
2930
let requestHandler = OAuthRequestManager.loadRequestInfo("oauth")
3031
if (requestHandler) {

src/main/oauth/ExternalOAuth2.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,16 @@ class ExternalOAuth2 {
2020
opts = opts || {};
2121

2222
var urlParams = {
23-
response_type: opts.scope || 'code',
23+
response_type: 'code',
2424
redirect_uri: this.#oauthInfo.redirectUri,
2525
client_id: this.#oauthInfo.clientId,
2626
state: this.#state
2727
};
2828

29+
if (opts.scope) {
30+
urlParams.scope = opts.scope;
31+
}
32+
2933
if (opts.accessType) {
3034
urlParams.access_type = opts.accessType;
3135
}

src/renderer/components/editor/Editor.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ export default function Editor({mode, onFinish}) {
198198

199199
ipcRenderer.send("disable-exist-prompt")
200200
}
201-
})
201+
}, [])
202202

203203
return (
204204
<Box className={classes.root}>
Lines changed: 67 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,136 +1,103 @@
1-
import React, { Component } from 'react'
1+
import React, { useEffect, useState } from 'react'
22
import { ipcRenderer } from 'electron'
3-
import autobind from 'autobind-decorator'
43
import update from 'immutability-helper'
54
import { Button } from '@material-ui/core'
65
import Loading from '../../../Loading'
76
import PhotoList from './PhotoList'
87

9-
class GooglePhotos extends Component {
108

11-
constructor(props, context) {
12-
super(props, context)
13-
this.state = {
14-
initialized: false,
15-
images: [],
16-
nextPageToken: null,
17-
fetching: false
18-
}
19-
}
20-
21-
componentWillMount() {
22-
ipcRenderer.on("receive-google-photos-images", this.handleReceiveImages)
23-
ipcRenderer.on("start-fetch-google-photos-images", this.handleStartFetch)
24-
ipcRenderer.on("receive-google-connected", this.handleReceiveConnected)
25-
}
26-
27-
componentWillUnmount() {
28-
ipcRenderer.removeListener("receive-google-photos-images", this.handleReceiveImages)
29-
ipcRenderer.removeListener("start-fetch-google-photos-images", this.handleStartFetch)
30-
ipcRenderer.removeListener("receive-google-connected", this.handleReceiveConnected)
31-
}
9+
export default function GooglePhotos({ connected, onConnect, onDisconnect, onSelectImage }) {
10+
const [initialized, setInitialized] = useState(false)
11+
const [images, setImages] = useState([])
12+
const [fetching, setFetching] = useState(false)
13+
const [nextPageToken, setNextPageToken] = useState(null)
3214

33-
componentDidMount() {
34-
this.handleRequestFetch()
35-
}
36-
37-
@autobind
38-
handleReceiveImages(e, data) {
39-
const { onConnect, onDisconnect } = this.props
40-
const { images, fetching } = this.state
15+
function handleReceiveImages(e, data) {
4116
if (data === null) {
4217
onDisconnect()
4318
return
4419
}
4520

46-
this.setState({
47-
initialized: true,
48-
images: update(images, {
49-
$push: data.images
50-
}),
51-
nextPageToken: data.nextPageToken,
52-
fetching: false
53-
})
21+
console.log("connected", data)
22+
23+
setInitialized(true)
24+
setImages(update(images, {
25+
$push: data.images
26+
}))
27+
setNextPageToken(data.nextPageToken)
28+
setFetching(false)
5429
onConnect(true)
5530
}
5631

57-
@autobind
58-
handleReceiveConnected(e, connected) {
59-
const { onConnect, onDisconnect } = this.props
32+
function handleStartFetch(e) {
33+
setFetching(true)
34+
}
35+
36+
function handleReceiveConnected(e, connected) {
37+
setInitialized(true)
38+
6039
if (connected) {
61-
this.setState({
62-
initialized: true,
63-
})
6440
onConnect()
6541
} else {
66-
this.setState({
67-
initialized: true,
68-
images: [],
69-
nextPageToken: null,
70-
})
42+
setImages([])
43+
setNextPageToken(null)
7144
onDisconnect()
7245
}
7346
}
7447

75-
@autobind
76-
handleStartFetch(e) {
77-
this.setState({
78-
fetching: true
79-
})
80-
}
81-
82-
@autobind
83-
handleRequestFetch() {
84-
const { nextPageToken } = this.state
48+
function handleRequestFetch() {
8549
ipcRenderer.send('fetch-google-photos-images', nextPageToken)
8650
}
8751

88-
@autobind
89-
handleRequestAuth() {
52+
function handleRequestAuth() {
9053
ipcRenderer.send("request-google-photos-auth")
9154
}
9255

93-
94-
@autobind
95-
handleImageSelect(image) {
96-
const { onSelectImage } = this.props
56+
function handleImageSelect(image) {
9757
if (confirm('이미지를 삽입하시겠습니까?')) {
9858
onSelectImage(image.url, image.title)
9959
}
10060
}
10161

102-
render() {
103-
const { connected } = this.props
104-
const { initialized, images, fetching } = this.state
105-
106-
if (!initialized) {
107-
return (
108-
<div className="google-photos-wrap">
109-
<div className="google-photos-cover">
110-
<Loading position='absolute' />
111-
</div>
112-
</div>
113-
)
114-
}
115-
116-
if (!connected) {
117-
return (
118-
<div className="google-photos-wrap">
119-
<div className="google-photos-cover">
120-
<Button variant='contained' className='btn btn_tistory' onClick={this.handleRequestAuth}>
121-
Google Photos 연결
122-
</Button>
123-
</div>
124-
</div>
125-
)
126-
}
62+
useEffect(() => {
63+
handleRequestFetch()
64+
ipcRenderer.on("receive-google-photos-images", handleReceiveImages)
65+
ipcRenderer.on("start-fetch-google-photos-images", handleStartFetch)
66+
ipcRenderer.on("receive-google-connected", handleReceiveConnected)
12767

128-
return (
129-
<PhotoList images={images} fetching={fetching}
130-
onFetch={this.handleRequestFetch}
131-
onClick={this.handleImageSelect} />
132-
)
133-
}
68+
return () => {
69+
ipcRenderer.removeListener("receive-google-photos-images", handleReceiveImages)
70+
ipcRenderer.removeListener("start-fetch-google-photos-images", handleStartFetch)
71+
ipcRenderer.removeListener("receive-google-connected", handleReceiveConnected)
72+
}
73+
}, [])
74+
75+
76+
if (!initialized) {
77+
return (
78+
<div className="google-photos-wrap">
79+
<div className="google-photos-cover">
80+
<Loading position='absolute' />
81+
</div>
82+
</div>
83+
)
84+
}
85+
86+
if (!connected) {
87+
return (
88+
<div className="google-photos-wrap">
89+
<div className="google-photos-cover">
90+
<Button variant='contained' className='btn btn_tistory' onClick={handleRequestAuth}>
91+
Google Photos 연결
92+
</Button>
93+
</div>
94+
</div>
95+
)
96+
}
97+
98+
return (
99+
<PhotoList images={images} fetching={fetching}
100+
onFetch={handleRequestFetch}
101+
onClick={handleImageSelect} />
102+
)
134103
}
135-
136-
export default GooglePhotos

0 commit comments

Comments
 (0)