Skip to content

Commit

Permalink
Handle auth for remote specifications
Browse files Browse the repository at this point in the history
  • Loading branch information
ulrikandersen committed Dec 4, 2024
1 parent 17b20b2 commit bde331e
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/app/api/remotes/[encryptedRemoteConfig]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ const RemoteSpecAuthSchema = z.object({
username: z.string(),
password: z.string(),
});
type RemoteSpecAuth = z.infer<typeof RemoteSpecAuthSchema>;
export type RemoteSpecAuth = z.infer<typeof RemoteSpecAuthSchema>;

const RemoteConfigSchema = z.object({
url: z.string().url(),
auth: RemoteSpecAuthSchema.optional(),
});
type RemoteConfig = z.infer<typeof RemoteConfigSchema>;
export type RemoteConfig = z.infer<typeof RemoteConfigSchema>;

export async function GET(req: NextRequest, { params }: { params: RemoteSpecificationParams }) {
const isAuthenticated = await session.getIsAuthenticated()
Expand Down
41 changes: 36 additions & 5 deletions src/features/projects/data/GitHubProjectDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,25 @@ import {
GitHubRepository,
GitHubRepositoryRef
} from "../domain"
import { RemoteConfig } from "@/app/api/remotes/[encryptedRemoteConfig]/route"
import RsaEncryptionService from "@/common/encryption/EncryptionService"
import { env } from "@/common"

export default class GitHubProjectDataSource implements IProjectDataSource {
private readonly repositoryDataSource: IGitHubRepositoryDataSource
private readonly repositoryNameSuffix: string
private readonly encryptionService: RsaEncryptionService

constructor(config: {
repositoryDataSource: IGitHubRepositoryDataSource
repositoryNameSuffix: string
}) {
this.repositoryDataSource = config.repositoryDataSource
this.repositoryNameSuffix = config.repositoryNameSuffix
this.encryptionService = new RsaEncryptionService({
publicKey: Buffer.from(env.getOrThrow("ENCRYPTION_PUBLIC_KEY_BASE_64"), "base64").toString("utf-8"),
privateKey: Buffer.from(env.getOrThrow("ENCRYPTION_PRIVATE_KEY_BASE_64"), "base64").toString("utf-8")
})
}

async getProjects(): Promise<Project[]> {
Expand Down Expand Up @@ -167,11 +175,34 @@ export default class GitHubProjectDataSource implements IProjectDataSource {
const existingVersionIdCount = versionIds.filter(e => e == baseVersionId).length
const versionId = baseVersionId + (existingVersionIdCount > 0 ? existingVersionIdCount : "")
const specifications = remoteVersion.specifications.map(e => {
return {
id: this.makeURLSafeID((e.id || e.name).toLowerCase()),
name: e.name,
url: "/api/remotes/EKNYViMOSUnJggD4c4UwEoOGkGKZIPjWtijfeoYqgrkRP%2FIwXa770oxwRsVTdVFzmbjWuartdrUhUjkq7EyT4m3NBQOph0UaRTQhFgxm4Q5v2KJ%2BkhJ6TTKwiEgEdS%2BdOvTzAzXtk80T4amaNdeET9JVGJo0y8G47qtUIZCWmyzxamTnOJYOhkj4NcH9XlyafghwUV%2FO%2FAShlzwscFPy%2BlDFuhl8jmYV4fvClI2%2F4iFyew%2Bg5LGvNXPTS8wEZcz9GBKrcgSE6ScK3oeAGesKPyYblkKiU7dAxi%2FlRs9jiKQId%2BEFLWFcDgNw8aLDyZjKMT2u4gF9dfLx4iRQhaJ7KQ%3D%3D"
}
if (e.auth) {
// decrypt username and password
const username = this.encryptionService.decrypt(e.auth.encryptedUsername)
const password = this.encryptionService.decrypt(e.auth.encryptedPassword)
// construct remote config
const remoteConfig: RemoteConfig = {
url: e.url,
auth: {
type: e.auth.type,
username,
password
}
}
// encrypt and encode remote config
const encryptedRemoteConfig = encodeURIComponent(this.encryptionService.encrypt(JSON.stringify(remoteConfig)))

return {
id: this.makeURLSafeID((e.id || e.name).toLowerCase()),
name: e.name,
url: `/api/remotes/${encryptedRemoteConfig}`
}
} else {
return {
id: this.makeURLSafeID((e.id || e.name).toLowerCase()),
name: e.name,
url: `/api/proxy?url=${encodeURIComponent(e.url)}`
}
}
})
versions.push({
id: versionId,
Expand Down
7 changes: 6 additions & 1 deletion src/features/projects/domain/IProjectConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import { z } from "zod"
export const ProjectConfigRemoteSpecificationSchema = z.object({
id: z.coerce.string().optional(),
name: z.coerce.string(),
url: z.string()
url: z.string(),
auth: z.object({
type: z.string(),
encryptedUsername: z.string(),
encryptedPassword: z.string()
}).optional(),
})

export const ProjectConfigRemoteVersionSchema = z.object({
Expand Down

0 comments on commit bde331e

Please sign in to comment.