encrypts integration secrets

This commit is contained in:
Christian Beutel
2025-02-08 11:48:21 +01:00
parent d01ca30932
commit d790f06216
20 changed files with 405 additions and 72 deletions

View File

@@ -9,6 +9,7 @@
type KomootIntegration,
type StravaIntegration,
} from "$lib/models/integration.js";
import { pb } from "$lib/pocketbase.js";
import {
integrations_create,
integrations_update,
@@ -29,7 +30,9 @@
);
let komootSettingsModal: KomootSettingsModal;
let komootToggleValue: boolean = $state(data.integration?.komoot?.active ?? false);
let komootToggleValue: boolean = $state(
data.integration?.komoot?.active ?? false,
);
async function onSettingsSave(
form: StravaIntegration | KomootIntegration,
@@ -97,6 +100,14 @@
type: "error",
});
}
show_toast({
text:
"strava " +
$_("integration-disabled"),
icon: "check",
type: "success",
});
}
}
@@ -105,14 +116,11 @@
return;
}
if (value) {
const authUrl = `https://api.komoot.de/v006/account/email/${integration.komoot.email}/`;
const r = await fetch(authUrl, {
method: "GET",
headers: {
Authorization: `Basic ${btoa(integration.komoot.email + ":" + integration.komoot.password)}`,
},
});
if (!r.ok) {
try {
await pb.send("/integration/komoot/login", {
method: "GET",
});
} catch (e) {
komootToggleValue = false;
show_toast({
text: $_("error-logging-in-to-komoot"),
@@ -133,6 +141,13 @@
type: "error",
});
}
show_toast({
text:
"komoot " + $_(`integration-${value ? "enabled" : "disabled"}`),
icon: "check",
type: "success",
});
}
</script>

View File

@@ -1,11 +1,13 @@
import { pb } from "$lib/pocketbase";
import { integrations_index, integrations_update } from "$lib/stores/integration_store";
import { error, redirect, type RequestEvent, type ServerLoad } from "@sveltejs/kit";
import { ClientResponseError } from "pocketbase";
export const load: ServerLoad = async ({ url, fetch }) => {
const oauthError = url.searchParams.get('error');
if (oauthError) {
// user cancelled
if(oauthError == "access_denied") {
if (oauthError == "access_denied") {
return redirect(302, '/settings/integrations')
}
return error(400, {
@@ -19,41 +21,23 @@ export const load: ServerLoad = async ({ url, fetch }) => {
});
}
const integrations = await integrations_index(fetch);
if (!integrations.length || !integrations[0].strava) {
return error(400, {
message: "Missing integration record"
try {
await pb.send("/integration/strava/token", {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
code,
grant_type: 'authorization_code'
})
});
} catch (e) {
console.error(e)
if (e instanceof ClientResponseError) {
return error(e.status, e.message);
}
throw e
}
const integration = integrations[0]
const tokenResponse = await fetch('https://www.strava.com/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
client_id: integration.strava?.clientId,
client_secret: integration.strava?.clientSecret,
code,
grant_type: 'authorization_code'
})
});
if (!tokenResponse.ok) {
const r = await tokenResponse.json()
console.error(r)
return error(500, 'Failed to get access token');
}
const { access_token, refresh_token, expires_at } = await tokenResponse.json();
integration.strava!.accessToken = access_token
integration.strava!.refreshToken = refresh_token
integration.strava!.expiresAt = expires_at
integration.strava!.active = true
await integrations_update(integration, fetch);
return redirect(302, '/settings/integrations')
}