mirror of
https://github.com/kennethnym/freya
synced 2026-06-23 18:05:11 +01:00
feat: add CalDAV source provider (#111)
Wire CalDavSourceProvider into the backend to support CalDAV calendar sources (e.g. iCloud) with basic auth. Config accepts serverUrl, username, lookAheadDays, and timeZone. Credentials (app-specific password) are stored encrypted via the existing credential storage infrastructure. Co-authored-by: Ona <no-reply@ona.com>
This commit is contained in:
53
apps/aelis-backend/src/caldav/provider.ts
Normal file
53
apps/aelis-backend/src/caldav/provider.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { CalDavSource } from "@aelis/source-caldav"
|
||||
import { type } from "arktype"
|
||||
|
||||
import type { FeedSourceProvider } from "../session/feed-source-provider.ts"
|
||||
|
||||
import { InvalidSourceCredentialsError } from "../sources/errors.ts"
|
||||
|
||||
const caldavConfig = type({
|
||||
"+": "reject",
|
||||
serverUrl: "string",
|
||||
username: "string",
|
||||
"lookAheadDays?": "number",
|
||||
"timeZone?": "string",
|
||||
})
|
||||
|
||||
const caldavCredentials = type({
|
||||
"+": "reject",
|
||||
password: "string",
|
||||
})
|
||||
|
||||
export class CalDavSourceProvider implements FeedSourceProvider {
|
||||
readonly sourceId = "aelis.caldav"
|
||||
readonly configSchema = caldavConfig
|
||||
|
||||
async feedSourceForUser(
|
||||
_userId: string,
|
||||
config: unknown,
|
||||
credentials: unknown,
|
||||
): Promise<CalDavSource> {
|
||||
const parsed = caldavConfig(config)
|
||||
if (parsed instanceof type.errors) {
|
||||
throw new Error(`Invalid CalDAV config: ${parsed.summary}`)
|
||||
}
|
||||
|
||||
if (!credentials) {
|
||||
throw new InvalidSourceCredentialsError("aelis.caldav", "No CalDAV credentials configured")
|
||||
}
|
||||
|
||||
const creds = caldavCredentials(credentials)
|
||||
if (creds instanceof type.errors) {
|
||||
throw new InvalidSourceCredentialsError("aelis.caldav", creds.summary)
|
||||
}
|
||||
|
||||
return new CalDavSource({
|
||||
serverUrl: parsed.serverUrl,
|
||||
authMethod: "basic",
|
||||
username: parsed.username,
|
||||
password: creds.password,
|
||||
lookAheadDays: parsed.lookAheadDays,
|
||||
timeZone: parsed.timeZone,
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user