kaneo (minimalist kanban) fork to experiment adding a tangled integration github.com/usekaneo/kaneo
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(auth): allow OIDC-only user registration

Tin 5e8600e8 e73fcb33

+65 -32
+13 -2
apps/api/src/auth.ts
··· 26 26 27 27 config(); 28 28 29 + const isRegistrationDisabled = process.env.DISABLE_REGISTRATION === "true"; 30 + const isPasswordRegistrationDisabled = 31 + process.env.DISABLE_PASSWORD_REGISTRATION === "true"; 32 + 29 33 const apiUrl = process.env.KANEO_API_URL || "http://localhost:1337"; 30 34 const clientUrl = process.env.KANEO_CLIENT_URL || "http://localhost:5173"; 31 35 const isHttps = apiUrl.startsWith("https://"); ··· 281 285 return; 282 286 } 283 287 284 - const isRegistrationDisabled = 285 - process.env.DISABLE_REGISTRATION === "true"; 288 + if (ctx.path === "/sign-up/email") { 289 + if (isPasswordRegistrationDisabled) { 290 + throw new APIError("FORBIDDEN", { 291 + message: 292 + "Password registration is currently disabled. Please use a configured social or OIDC sign-in method.", 293 + }); 294 + } 295 + } 296 + 286 297 if (!isRegistrationDisabled) { 287 298 return; 288 299 }
+1
apps/api/src/schemas.ts
··· 123 123 124 124 export const configSchema = v.object({ 125 125 disableRegistration: v.nullable(v.boolean()), 126 + disablePasswordRegistration: v.nullable(v.boolean()), 126 127 isDemoMode: v.boolean(), 127 128 hasSmtp: v.boolean(), 128 129 hasGithubSignIn: v.nullable(v.boolean()),
+2
apps/api/src/utils/get-settings.ts
··· 5 5 function getSettings() { 6 6 return { 7 7 disableRegistration: process.env.DISABLE_REGISTRATION === "true", 8 + disablePasswordRegistration: 9 + process.env.DISABLE_PASSWORD_REGISTRATION === "true", 8 10 isDemoMode: process.env.DEMO_MODE === "true", 9 11 hasSmtp: 10 12 Boolean(process.env.SMTP_HOST) &&
+1
apps/docs/core/installation/environment-variables.mdx
··· 78 78 --- | --- | --- | 79 79 | `DISABLE_GUEST_ACCESS` | Disable anonymous/guest sign-in. When set to `true`, the guest access button will not be shown on sign-in and sign-up pages. | `false` | 80 80 | `DISABLE_REGISTRATION` | Disable public user registration. When set to `true`, the sign-up option will not be shown on the sign-in page and new user creation is blocked (including via SSO). **Note:** Users with valid workspace invitations can still register even when this is enabled. | `false` | 81 + | `DISABLE_PASSWORD_REGISTRATION` | Disable password-based account creation. When set to `true`, email/password sign-up is blocked, but social/OIDC registration remains available unless `DISABLE_REGISTRATION=true`. | `false` | 81 82 82 83 ### GitHub SSO & Integration 83 84
+1 -1
apps/web/src/components/auth/toggle.tsx
··· 10 10 export function AuthToggle({ message, linkText, linkTo }: AuthToggleProps) { 11 11 const { data: config } = useGetConfig(); 12 12 13 - if (config?.disableRegistration) { 13 + if (config?.disableRegistration || config?.disablePasswordRegistration) { 14 14 return null; 15 15 } 16 16
+5 -8
apps/web/src/routes/auth/sign-in.tsx
··· 355 355 onSuccess={handleSignInSuccess} 356 356 /> 357 357 )} 358 - {config?.disableRegistration ? ( 358 + {config?.disableRegistration || 359 + config?.disablePasswordRegistration ? ( 359 360 <div className="text-center pt-4"> 360 361 <p className="text-sm text-muted-foreground"> 361 - Don't have an account?{" "} 362 - <a 363 - href="/auth/sign-up" 364 - className="text-primary hover:underline font-medium" 365 - > 366 - Sign up with invitation 367 - </a> 362 + {config?.disableRegistration 363 + ? "Public registration is disabled. Use an invitation to create an account." 364 + : "Password registration is disabled. Use a configured social or OIDC sign-in method to create an account."} 368 365 </p> 369 366 </div> 370 367 ) : (
+37 -20
apps/web/src/routes/auth/sign-up.tsx
··· 63 63 ? "Create an account to accept your invitation" 64 64 : config?.disableRegistration 65 65 ? "Registration requires an invitation" 66 - : "Get started with your workspace" 66 + : config?.disablePasswordRegistration 67 + ? "Use social or OIDC sign-in to create an account" 68 + : "Get started with your workspace" 67 69 } 68 70 > 69 71 <div className="space-y-4 mt-6"> ··· 84 86 </AlertDescription> 85 87 </Alert> 86 88 )} 89 + {config?.disablePasswordRegistration && ( 90 + <Alert> 91 + <AlertDescription> 92 + Password-based account creation is disabled. Use a configured 93 + social or OIDC sign-in method from the sign-in page. 94 + </AlertDescription> 95 + </Alert> 96 + )} 87 97 88 - {config?.hasGuestAccess && !invitationId && ( 89 - <> 90 - <Button 91 - variant="outline" 92 - onClick={handleGuestAccess} 93 - disabled={isGuestLoading} 94 - className="w-full mb-0" 95 - size="sm" 96 - > 97 - <UserCheck className="w-4 h-4 mr-2" /> 98 - {isGuestLoading ? "Signing in..." : "Continue as guest"} 99 - </Button> 100 - <div className="flex items-center gap-4 my-4"> 101 - <div className="flex-1 h-px bg-border" /> 102 - <span className="text-sm text-muted-foreground">or</span> 103 - <div className="flex-1 h-px bg-border" /> 104 - </div> 105 - </> 98 + {config?.hasGuestAccess && 99 + !invitationId && 100 + !config?.disablePasswordRegistration && ( 101 + <> 102 + <Button 103 + variant="outline" 104 + onClick={handleGuestAccess} 105 + disabled={isGuestLoading} 106 + className="w-full mb-0" 107 + size="sm" 108 + > 109 + <UserCheck className="w-4 h-4 mr-2" /> 110 + {isGuestLoading ? "Signing in..." : "Continue as guest"} 111 + </Button> 112 + <div className="flex items-center gap-4 my-4"> 113 + <div className="flex-1 h-px bg-border" /> 114 + <span className="text-sm text-muted-foreground">or</span> 115 + <div className="flex-1 h-px bg-border" /> 116 + </div> 117 + </> 118 + )} 119 + {!config?.disablePasswordRegistration && ( 120 + <SignUpForm 121 + invitationId={invitationId} 122 + defaultEmail={prefillEmail} 123 + /> 106 124 )} 107 - <SignUpForm invitationId={invitationId} defaultEmail={prefillEmail} /> 108 125 <AuthToggle 109 126 message="Already have an account?" 110 127 linkText="Sign in"
+1
charts/kaneo/README.md
··· 133 133 | `api.env.existingSecret.name` | Name of the existing secret containing the JWT access token | `""` | 134 134 | `api.env.existingSecret.key` | Key in the existing secret that contains the JWT access token | `jwt-access` | 135 135 | `api.env.disableRegistration` | Disable new user registration | `false` | 136 + | `api.env.disablePasswordRegistration` | Disable password-based account creation while keeping social/OIDC registration available | `false` | 136 137 | `api.env.database.external.enabled` | Use external PostgreSQL database (set postgresql.enabled to false) | `false` | 137 138 | `api.env.database.external.host` | External PostgreSQL host | `""` | 138 139 | `api.env.database.external.port` | External PostgreSQL port | `5432` |
+3 -1
charts/kaneo/templates/deployment.yaml
··· 88 88 {{- end }} 89 89 - name: DISABLE_REGISTRATION 90 90 value: {{ .Values.api.env.disableRegistration | quote }} 91 + - name: DISABLE_PASSWORD_REGISTRATION 92 + value: {{ .Values.api.env.disablePasswordRegistration | quote }} 91 93 livenessProbe: 92 94 {{- toYaml .Values.api.livenessProbe | nindent 12 }} 93 95 readinessProbe: ··· 129 131 {{- with .Values.tolerations }} 130 132 tolerations: 131 133 {{- toYaml . | nindent 8 }} 132 - {{- end }} 134 + {{- end }}
+1
charts/kaneo/values.yaml
··· 87 87 name: "" 88 88 key: auth-secret 89 89 disableRegistration: false 90 + disablePasswordRegistration: false 90 91 # Database configuration 91 92 database: 92 93 # Use external PostgreSQL (set postgresql.enabled to false)