diff --git a/auth.js b/auth.js index 250003e..aa232ea 100644 --- a/auth.js +++ b/auth.js @@ -4,6 +4,7 @@ export class Auth { constructor({ baseUrl, remoteBaseUrl, + giteaAppBaseUrl, giteaApiBaseUrl, giteaWebBaseUrl, giteaClientId, @@ -11,6 +12,7 @@ export class Auth { }) { this.baseUrl = baseUrl this.remoteBaseUrl = remoteBaseUrl + this.giteaAppBaseUrl = giteaAppBaseUrl this.giteaApiBaseUrl = giteaApiBaseUrl this.giteaWebBaseUrl = giteaWebBaseUrl this.giteaClientId = giteaClientId @@ -24,10 +26,7 @@ export class Auth { const search = new URLSearchParams() search.set('response_type', 'code') search.set('client_id', this.giteaClientId) - search.set( - 'redirect_uri', - this.remoteBaseUrl + '/api/auth/callback' - ) + search.set('redirect_uri', this.callbackUrl) search.set('state', state) url.search = search.toString() return url.toString() @@ -40,6 +39,10 @@ export class Auth { return `${randomInt}-${timestamp}` } + get callbackUrl() { + return this.remoteBaseUrl + '/api/auth/callback' + } + async redirect(event) { const state = this.buildState() const url = this.redirectUrl(state) @@ -56,9 +59,47 @@ export class Auth { })) } - getToken(code) { - this._code = code - return 'test' + get tokenEndpoint() { + return ( + this.giteaAppBaseUrl + + '/login/oauth/access_token' + ) + } + + async getToken(code) { + const resp = await fetch(this.tokenEndpoint, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + grant_type: 'authorization_code', + code, + client_id: this.giteaClientId, + client_secret: this.giteaClientSecret, + redirect_uri: this.callbackUrl, + }), + }) + return await resp.json() + } + + saveTokens(headers, data) { + cookie.setCookie(headers, { + name: 'oauth.gitea.accessToken', + value: data.access_token, + }) + cookie.setCookie(headers, { + name: 'oauth.gitea.refreshToken', + value: data.refresh_token, + }) + cookie.setCookie(headers, { + name: 'oauth.gitea.expires', + value: String( + Math.floor(new Date().valueOf() / 1000) + + data.expires_in + ), + }) } async callback(event) { @@ -78,18 +119,42 @@ export class Auth { })) return } - const token = await this.getToken(code) + const data = await this.getToken(code) cookie.deleteCookie(headers, 'oauth.gitea.state') - cookie.setCookie(headers, { - name: 'oauth.gitea.token', - value: token, - }) + this.saveTokens(headers, data) event.respondWith(new Response('', { headers, status: 302, })) } + async refreshToken(refresh_token) { + const resp = await fetch(this.tokenEndpoint, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + refresh_token, + grant_type: 'refresh_token', + }) + }) + return await resp.json() + } + + async refresh(event) { + const headers = new Headers() + const cookies = cookie.getCookies( + event.request.headers + ) + const data = await this.refreshToken(body) + this.saveTokens(headers, data) + event.respondWith( + new Response(JSON.stringify({}), {headers}) + ) + } + async serve(event) { const {pathname} = new URL(event.request.url) const u = this.baseUrl @@ -97,6 +162,8 @@ export class Auth { await this.redirect(event) } else if (pathname === `${u}/api/auth/callback`) { await this.callback(event) + } else if (pathname === `${u}/api/auth/refresh`) { + await this.refresh(event) } else { event.respondWith(new Response( 'Not Found', {status: 404} diff --git a/server.js b/server.js index 3a978b8..b94c8d8 100644 --- a/server.js +++ b/server.js @@ -51,6 +51,7 @@ export class Server { this.auth = new Auth({ baseUrl: this.baseUrl, remoteBaseUrl: this.remoteBaseUrl, + giteaAppBaseUrl: this.giteaAppBaseUrl, giteaApiBaseUrl: this.giteaApiBaseUrl, giteaWebBaseUrl: this.giteaWebBaseUrl, giteaClientId: this.giteaClientId,