Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes Issue #66 : Added a switch on dashboard to disable new signups but keep allowing logins #74

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "ProjectConfig" ADD COLUMN "signUpEnabled" BOOLEAN NOT NULL DEFAULT true;
1 change: 1 addition & 0 deletions packages/stack-server/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ model ProjectConfig {
allowLocalhost Boolean
credentialEnabled Boolean
magicLinkEnabled Boolean
signUpEnabled Boolean @default(true)
createTeamOnSignUp Boolean

projects Project[]
Expand Down
1 change: 1 addition & 0 deletions packages/stack-server/prisma/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ async function seed() {
},
credentialEnabled: true,
magicLinkEnabled: true,
signUpEnabled: true,
createTeamOnSignUp: false,
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default function PageClient () {
id: "id",
credentialEnabled: form.watch("signInMethods").includes("credential"),
magicLinkEnabled: form.watch("signInMethods").includes("magicLink"),
signUpEnabled:true,
oauthProviders: (["google", "facebook", "github", "microsoft"] as const).map(provider => ({
id: provider,
enabled: form.watch("signInMethods").includes(provider),
Expand All @@ -56,6 +57,7 @@ export default function PageClient () {
config: {
credentialEnabled: values.signInMethods.includes("credential"),
magicLinkEnabled: values.signInMethods.includes("magicLink"),
signUpEnabled:true,
oauthProviders: (["google", "facebook", "github", "microsoft"] as const).map(provider => ({
id: provider,
enabled: values.signInMethods.includes(provider),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,22 @@ export default function PageClient() {
});
}}
/>;
})}
})}
</SettingCard>
</PageLayout>

<SettingCard title="User Settings" description="Toggle to enable/disable new User Sign-up">
<SettingSwitch
label="Signup"
checked={project.evaluatedConfig.signUpEnabled}
onCheckedChange={async (checked) => {
await project.update({
config: {
signUpEnabled: checked,
},
});
}}
/>
</SettingCard>
</PageLayout >
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ export const GET = deprecatedSmartRouteHandler(async (req: NextRequest, options:
throw new StatusError(StatusError.NotFound, "Provider not found or not enabled");
}

if (!project.evaluatedConfig.signUpEnabled) {
throw new StatusError(StatusError.Forbidden, "new signup is not enabled");
}

const userInfo = await getProvider(provider).getCallback({
codeVerifier: innerCodeVerifier,
state: innerState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ export const POST = deprecatedSmartRouteHandler(async (req: NextRequest) => {
throw new StatusError(StatusError.Forbidden, "Magic link is not enabled for this project");
}

if (!project.evaluatedConfig.signUpEnabled) {
throw new StatusError(StatusError.Forbidden, "new signup is not enabled");
}

const users = await prismaClient.projectUser.findMany({
where: {
projectId,
Expand Down
4 changes: 4 additions & 0 deletions packages/stack-server/src/app/api/v1/auth/signup/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ export const POST = deprecatedSmartRouteHandler(async (req: NextRequest) => {
throw new StatusError(StatusError.Forbidden, "Password authentication is not enabled");
}

if (!project.evaluatedConfig.signUpEnabled) {
throw new StatusError(StatusError.Forbidden, "new signup is not enabled");
}

if (
!validateUrl(
emailVerificationRedirectUrl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const handler = deprecatedSmartRouteHandler(async (req: NextRequest, options: {
id: project.id,
credentialEnabled: project.evaluatedConfig.credentialEnabled,
magicLinkEnabled: project.evaluatedConfig.magicLinkEnabled,
signUpEnabled: project.evaluatedConfig.signUpEnabled,
oauthProviders: project.evaluatedConfig.oauthProviders.map(
(provider) => ({
id: provider.id,
Expand Down
5 changes: 5 additions & 0 deletions packages/stack-server/src/lib/projects.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ export async function createProject(
allowLocalhost: projectOptions.config?.allowLocalhost ?? true,
credentialEnabled: !!projectOptions.config?.credentialEnabled,
magicLinkEnabled: !!projectOptions.config?.magicLinkEnabled,
signUpEnabled: !!projectOptions.config?.signUpEnabled ?? true,
createTeamOnSignUp: !!projectOptions.config?.createTeamOnSignUp,
emailServiceConfig: {
create: {
Expand Down Expand Up @@ -469,6 +470,7 @@ export async function updateProject(
data: {
credentialEnabled: options.config?.credentialEnabled,
magicLinkEnabled: options.config?.magicLinkEnabled,
signUpEnabled:options.config?.signUpEnabled,
allowLocalhost: options.config?.allowLocalhost,
createTeamOnSignUp: options.config?.createTeamOnSignUp,
},
Expand Down Expand Up @@ -531,6 +533,7 @@ export function projectJsonFromDbType(project: ProjectDB): ProjectJson {
allowLocalhost: project.config.allowLocalhost,
credentialEnabled: project.config.credentialEnabled,
magicLinkEnabled: project.config.magicLinkEnabled,
signUpEnabled: project.config.signUpEnabled,
createTeamOnSignUp: project.config.createTeamOnSignUp,
domains: project.config.domains.map((domain) => ({
domain: domain.domain,
Expand Down Expand Up @@ -592,6 +595,7 @@ const nonRequiredSchemas = {
).optional().default(undefined),
credentialEnabled: yup.boolean().optional(),
magicLinkEnabled: yup.boolean().optional(),
signUpEnabled: yup.boolean().optional(),
allowLocalhost: yup.boolean().optional(),
createTeamOnSignUp: yup.boolean().optional(),
emailConfig: yup.object({
Expand Down Expand Up @@ -628,6 +632,7 @@ export const projectSchemaToUpdateOptions = (
allowLocalhost: update.config.allowLocalhost,
credentialEnabled: update.config.credentialEnabled,
magicLinkEnabled: update.config.magicLinkEnabled,
signUpEnabled:update.config.signUpEnabled,
createTeamOnSignUp: update.config.createTeamOnSignUp,
oauthProviders: update.config.oauthProviders && update.config.oauthProviders.map((provider) => {
if (sharedProviders.includes(provider.type as SharedProvider)) {
Expand Down
1 change: 1 addition & 0 deletions packages/stack-shared/src/interface/adminInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export type ProjectUpdateOptions = {
credentialEnabled?: boolean,
magicLinkEnabled?: boolean,
allowLocalhost?: boolean,
signUpEnabled?: boolean,
createTeamOnSignUp?: boolean,
emailConfig?: EmailConfigJson,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/stack-shared/src/interface/clientInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export type ClientProjectJson = {
id: string,
credentialEnabled: boolean,
magicLinkEnabled: boolean,
signUpEnabled: boolean,
oauthProviders: {
id: string,
enabled: boolean,
Expand Down Expand Up @@ -95,6 +96,7 @@ export type ProjectJson = {
allowLocalhost: boolean,
credentialEnabled: boolean,
magicLinkEnabled: boolean,
signUpEnabled:boolean,
oauthProviders: OAuthProviderConfigJson[],
emailConfig?: EmailConfigJson,
domains: DomainConfigJson[],
Expand Down
2 changes: 2 additions & 0 deletions packages/stack/src/lib/stack-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,7 @@ class _StackClientAppImpl<HasTokenStore extends boolean, ProjectId extends strin
id: data.evaluatedConfig.id,
credentialEnabled: data.evaluatedConfig.credentialEnabled,
magicLinkEnabled: data.evaluatedConfig.magicLinkEnabled,
signUpEnabled:data.evaluatedConfig.signUpEnabled,
allowLocalhost: data.evaluatedConfig.allowLocalhost,
oauthProviders: data.evaluatedConfig.oauthProviders,
emailConfig: data.evaluatedConfig.emailConfig,
Expand Down Expand Up @@ -1968,6 +1969,7 @@ export type Project = {
readonly allowLocalhost: boolean,
readonly credentialEnabled: boolean,
readonly magicLinkEnabled: boolean,
readonly signUpEnabled: boolean,
readonly oauthProviders: OAuthProviderConfig[],
readonly emailConfig?: EmailConfig,
readonly domains: DomainConfig[],
Expand Down