Skip to content

Commit 7ed2b21

Browse files
André DietrichAndré Dietrich
authored andcommitted
fix: GitHub gist export
1 parent 0fb88a0 commit 7ed2b21

4 files changed

Lines changed: 118 additions & 50 deletions

File tree

src/i18n/de.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@
122122
},
123123
"github": {
124124
"exporting": "Wird zu GitHub Gist exportiert...",
125-
"badCredentials": "Ungültige Anmeldedaten, Seite wird neu geladen"
125+
"badCredentials": "Ungültige Anmeldedaten, Seite wird neu geladen",
126+
"error": "Der Export zu GitHub ist fehlgeschlagen:"
126127
},
127128
"nostr": {
128129
"title": "Via Nostr teilen",

src/i18n/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@
122122
},
123123
"github": {
124124
"exporting": "Exporting to GitHub gist...",
125-
"badCredentials": "Bad credentials, reloading page"
125+
"badCredentials": "Bad credentials, reloading page",
126+
"error": "The export to GitHub failed:"
126127
},
127128
"nostr": {
128129
"title": "Share via Nostr",

src/ts/GitHub.ts

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,34 @@ export async function access_token(code: string) {
5656
{ method: 'post' }
5757
)
5858

59+
if (!response.ok) {
60+
return {
61+
error: 'access_token',
62+
message: 'GitHub token request failed (' + response.status + ')',
63+
}
64+
}
65+
5966
const json = await response.json()
6067

6168
// headers not working that is why contents has to be split manually
6269
const credentials = getParams(json.contents)
6370

71+
// GitHub returns error=... instead of access_token/scope when the
72+
// (single-use) OAuth code is invalid or expired
73+
if (!credentials.access_token) {
74+
return {
75+
error: 'access_token',
76+
message: credentials.error_description || 'Could not obtain access token',
77+
}
78+
}
79+
6480
return credentials
6581
} catch (e) {
6682
console.warn(e)
67-
return
83+
return {
84+
error: 'access_token',
85+
message: 'Could not obtain access token',
86+
}
6887
}
6988
}
7089

@@ -93,20 +112,36 @@ export async function gistUpload(
93112
gist_id = ''
94113
}
95114

96-
const response = await fetch('https://api.github.com/gists' + gist_id, {
97-
headers: {
98-
'User-Agent': 'LiaScript',
99-
Authorization: credentials.token_type + ' ' + credentials.access_token,
100-
Accept: 'application/vnd.github+json',
101-
},
102-
method: 'post',
103-
body: JSON.stringify(gist),
104-
})
115+
if (!credentials?.access_token) {
116+
return {
117+
error: 'Bad credentials',
118+
message: 'Missing access token',
119+
}
120+
}
105121

106-
const json = await response.json()
122+
let json
123+
try {
124+
const response = await fetch('https://api.github.com/gists' + gist_id, {
125+
headers: {
126+
'User-Agent': 'LiaScript',
127+
Authorization: credentials.token_type + ' ' + credentials.access_token,
128+
Accept: 'application/vnd.github+json',
129+
},
130+
method: 'post',
131+
body: JSON.stringify(gist),
132+
})
133+
134+
json = await response.json()
135+
} catch (e) {
136+
console.warn(e)
137+
return {
138+
error: 'network',
139+
message: 'Could not reach GitHub',
140+
}
141+
}
107142

108143
// the gist does not exist anymore (has been deleted)
109-
if (json.message == 'Not Found') {
144+
if (json.message == 'Not Found' && gist_id) {
110145
return await gistUpload(credentials, title, comment, content)
111146
}
112147
// probably the user has revoked the credentials,
@@ -118,6 +153,14 @@ export async function gistUpload(
118153
}
119154
}
120155

156+
// any other error (rate limit, validation, 4xx/5xx) has no `files`
157+
if (!json.files) {
158+
return {
159+
error: 'upload',
160+
message: json.message || 'Gist upload failed',
161+
}
162+
}
163+
121164
return {
122165
url: json.html_url,
123166
id: json.id,

src/views/Export/GitHub.vue

Lines changed: 59 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -34,42 +34,65 @@ export default {
3434
const provider = new IndexeddbPersistence(id, yDoc);
3535
3636
provider.on("synced", async (_: any) => {
37-
const metaData = await meta;
38-
const contentData = yDoc.getText(id).toJSON();
39-
40-
if (!config.credentials?.github?.scope) {
41-
config.credentials.github = await GitHub.access_token(code);
42-
Utils.storeConfig(config);
43-
}
44-
45-
const gist = await GitHub.gistUpload(
46-
config.credentials.github,
47-
metaData.meta.title,
48-
metaData.meta.macro?.comment || "",
49-
contentData,
50-
metaData.meta.gist_id
51-
);
52-
53-
if (gist.error == "Bad credentials") {
54-
config.credentials.github = undefined;
55-
Utils.storeConfig(config);
56-
57-
this.message = this.$t('github.badCredentials');
58-
59-
window.location.reload();
60-
}
61-
62-
if (metaData.meta.gist_id != gist.id) {
63-
await database.put(id, {
64-
gist_id: gist.id,
65-
gist_url: gist.raw_url,
66-
});
67-
}
68-
69-
this.message = gist.message;
70-
71-
if (gist.url) {
72-
window.location.href = gist.url;
37+
try {
38+
const metaData = await meta;
39+
const contentData = yDoc.getText(id).toJSON();
40+
41+
if (!config.credentials?.github?.scope) {
42+
const credentials = await GitHub.access_token(code);
43+
44+
// could not obtain a token (e.g. expired/invalid OAuth code)
45+
if (credentials?.error) {
46+
config.credentials.github = undefined;
47+
Utils.storeConfig(config);
48+
49+
this.message = this.$t('github.error') + "\n" + credentials.message;
50+
return;
51+
}
52+
53+
config.credentials.github = credentials;
54+
Utils.storeConfig(config);
55+
}
56+
57+
const gist = await GitHub.gistUpload(
58+
config.credentials.github,
59+
metaData.meta.title,
60+
metaData.meta.macro?.comment || "",
61+
contentData,
62+
metaData.meta.gist_id
63+
);
64+
65+
if (gist.error == "Bad credentials") {
66+
config.credentials.github = undefined;
67+
Utils.storeConfig(config);
68+
69+
this.message = this.$t('github.badCredentials');
70+
71+
window.location.reload();
72+
return;
73+
}
74+
75+
// any other upload/network error: show it instead of hanging
76+
if (gist.error) {
77+
this.message = this.$t('github.error') + "\n" + gist.message;
78+
return;
79+
}
80+
81+
if (metaData.meta.gist_id != gist.id) {
82+
await database.put(id, {
83+
gist_id: gist.id,
84+
gist_url: gist.raw_url,
85+
});
86+
}
87+
88+
this.message = gist.message;
89+
90+
if (gist.url) {
91+
window.location.href = gist.url;
92+
}
93+
} catch (e) {
94+
console.warn(e);
95+
this.message = this.$t('github.error') + "\n" + (e?.message || e);
7396
}
7497
});
7598
},

0 commit comments

Comments
 (0)