mirror of
https://github.com/Dvorinka/Containr.git
synced 2026-10-29 00:01:22 +00:00
feat(git): GitHub App manifest self-provisioning + app-level webhook (#44)
* feat(branding): white-label — public /branding, admin write, shell theming app_settings branding.* keys (product name, logo/favicon URLs, accent color, docs/support links). Public GET /branding so login and shell theme pre-auth; admin writes via PUT /settings. useBranding() applies document.title, accent CSS var and favicon; BrandWordmark replaces hardcoded wordmarks; admin Platform settings gain a Branding form. MCP containr_branding_get + settings_update. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> * feat(invites): team invite links — admin create/revoke, public accept Admins mint single-use invite links (sha256-hashed token at rest, optional email binding, configurable TTL). Public endpoints let the accept page validate the link and register — working even while public signup is disabled. - migration + sqlc queries/model for user_invites - POST /admin/invites (returns one-time token+url), GET list, DELETE revoke - GET /auth/invites/:token public validation, POST /auth/accept-invite - CLI containr invites list|create|revoke; MCP invites tools - /auth/accept-invite page (expired/used/invalid states, bound-email lock) - Admin page Team invites section: create, copy link, revoke - OpenAPI + generated types + CLI guide Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> * feat(admin): impersonate user — 15-min token, audit-logged POST /admin/users/:id/impersonate mints a short-lived bearer token (impersonated_by claim) for support/debugging. Admin accounts cannot be impersonated; every mint is audit-logged with actor + target. - CLI: containr admin impersonate <user-id> (works via CONTAINR_TOKEN) - MCP: containr_admin_impersonate - Admin UI: per-user Impersonate action → token modal with usage hint - OpenAPI + generated types Verified live: token resolves to target, admin target 403, audit row. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> * feat(git): GitHub App manifest self-provisioning + app-level webhook Admins create the instance GitHub App in-browser instead of hand- setting GITHUB_APP_* env vars: - POST /admin/git/github-app/manifest builds the manifest + URL; the frontend auto-submits it to github.com - /git/github-app/callback page exchanges the code via POST /admin/git/github-app/convert; credentials persist in app_settings (precedence over env) - GET /admin/git/github-app reports configured/source - POST /api/git/github-app/webhook — single app-level push receiver, HMAC-verified, dispatches via extracted dispatchPushToServices - install-url + installation-token paths resolve settings→env - CLI: containr admin github-app status|manifest|convert; MCP tools - Git providers UI shows "Set up GitHub App" for admins when unconfigured Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
50e39fe140
commit
00e69b3733
16 files changed
+1184
-28
No files matched your search
@@ -133,7 +133,9 @@ func handleGetGitProviders(c *gin.Context) {
|
||||
}
|
||||
|
||||
func handleGetGitHubAppInstallURL(c *gin.Context) {
|
||||
slug := strings.TrimSpace(os.Getenv("GITHUB_APP_SLUG"))
|
||||
db, _ := c.Get("db")
|
||||
d, _ := db.(*database.DB)
|
||||
slug := strings.TrimSpace(settingValue(d, settingGitHubAppSlug, "GITHUB_APP_SLUG", ""))
|
||||
if slug == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "GITHUB_APP_SLUG is not configured"})
|
||||
return
|
||||
@@ -1073,8 +1075,8 @@ func fetchBitbucketRepositories(providerAPIURL, accessToken string) ([]remoteGit
|
||||
}
|
||||
|
||||
func getGitHubAppInstallationToken(baseURL string, installationID int64) (string, error) {
|
||||
appID := strings.TrimSpace(os.Getenv("GITHUB_APP_ID"))
|
||||
privateKeyPEM := strings.TrimSpace(os.Getenv("GITHUB_APP_PRIVATE_KEY"))
|
||||
appID := platformSetting(settingGitHubAppID, "GITHUB_APP_ID")
|
||||
privateKeyPEM := platformSetting(settingGitHubAppPrivateKey, "GITHUB_APP_PRIVATE_KEY")
|
||||
if appID == "" || privateKeyPEM == "" {
|
||||
return "", fmt.Errorf("GITHUB_APP_ID and GITHUB_APP_PRIVATE_KEY must be configured")
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user