Skip to content

Sub task/implement configurable login registration via code core 10#669

Merged
irumvanselme merged 2 commits into
mainfrom
sub-task/implement-configurable-login-registration-via-code-CORE-10
Feb 5, 2026
Merged

Sub task/implement configurable login registration via code core 10#669
irumvanselme merged 2 commits into
mainfrom
sub-task/implement-configurable-login-registration-via-code-CORE-10

Conversation

@irumvanselme

Copy link
Copy Markdown
Collaborator

No description provided.

@irumvanselme
irumvanselme force-pushed the sub-task/implement-configurable-login-registration-via-code-CORE-10 branch 2 times, most recently from 6b96839 to 059dd97 Compare February 3, 2026 12:45
@Fidesnoella
Fidesnoella requested a review from Copilot February 3, 2026 13:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds configuration to disable/bypass invitation-code prompts for login/registration, with coordinated frontend UI changes and backend validation updates.

Changes:

  • Renames the login-code disable env var to GLOBAL_DISABLE_LOGIN_CODE across IaC + frontend.
  • Introduces GLOBAL_DISABLE_REGISTRATION_CODE to optionally hide the registration code UI and allow registered users to create preferences without a code.
  • Refactors invitation-code validation in the backend via new validator classes, and expands frontend/backend test coverage for these flows.

Reviewed changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
iac/templates/env.template Renames login disable env var in the deployment env template.
iac/frontend/prepare_frontend.py Updates env.js generation to use GLOBAL_DISABLE_LOGIN_CODE.
iac/.env.example Updates example env var name for disabling login code.
frontend-new/src/userPreferences/UserPreferencesService/userPreferences.types.ts Makes invitation_code optional at the type level for preference creation.
frontend-new/src/envService.ts Adds env var entries/getters for GLOBAL_DISABLE_LOGIN_CODE and GLOBAL_DISABLE_REGISTRATION_CODE.
frontend-new/src/envService.test.ts Updates/extends tests for the new env getters/keys.
frontend-new/src/auth/services/FirebaseAuthenticationService/emailAuth/FirebaseEmailAuthentication.service.ts Allows email registration to proceed without a registration code (when bypassed).
frontend-new/src/auth/services/FirebaseAuthenticationService/emailAuth/FirebaseEmailAuthentication.service.test.ts Adds tests for registration without code and additional auth/token behaviors.
frontend-new/src/auth/services/Authentication.service.ts Updates successful-registration API to accept an optional registration code.
frontend-new/src/auth/services/Authentication.service.test.ts Adds coverage for successful registration with/without invitation codes.
frontend-new/src/auth/pages/Register/Register.tsx Hides registration-code UI and passes undefined when registration code bypass is enabled.
frontend-new/src/auth/pages/Register/Register.test.tsx Adds tests for registration code bypass behavior and additional error-handling/navigation cases.
frontend-new/src/auth/pages/Login/Login.stories.tsx Updates Storybook config to use GLOBAL_DISABLE_LOGIN_CODE.
frontend-new/src/auth/pages/Landing/Landing.stories.tsx Updates Storybook config to use GLOBAL_DISABLE_LOGIN_CODE.
frontend-new/src/auth/components/SocialAuth/SocialAuth.tsx Allows social registration without code when bypass enabled; adjusts modal behavior.
frontend-new/src/auth/components/SocialAuth/SocialAuth.test.tsx Adds extensive tests for social auth registration and error handling.
frontend-new/src/_test_utilities/envServiceMock.ts Extends envService mock with getRegistrationCodeDisabled.
frontend-new/public/data/env.example.js Adds example config values for the new global disable flags.
frontend-new/README.md Documents the new env vars and intended operational/security usage.
backend/common_libs/test_utilities/setup_env_vars.py Adds default for GLOBAL_DISABLE_REGISTRATION_CODE in backend test env setup.
backend/app/users/validators.py Introduces new validators for invitation-code rules + bypass behavior.
backend/app/users/types.py Makes invitation_code optional in the create-preferences request model.
backend/app/users/test_validators.py Adds unit tests for the new validator logic.
backend/app/users/preferences.py Replaces inline invitation validation with validator strategy; supports bypass mode.
backend/app/server.py Reads GLOBAL_DISABLE_REGISTRATION_CODE and injects it into ApplicationConfig.
backend/app/app_config.py Adds disable_registration_code to application config.
backend/README.md Documents GLOBAL_DISABLE_REGISTRATION_CODE and coordination with frontend.
backend/.env.example Adds example env var for registration code bypass.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +133 to 136
async onSuccessfulRegistration(token: string, registrationCode: string | undefined): Promise<void> {
const user = this.getUser(token);
if (!user) {
throw Error("User not found in the token");

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

registrationCode was widened to string | undefined, but onSuccessfulRegistration still needs to ensure the createUserPreferences(...) payload matches the CreateUserPreferencesSpec contract (i.e., omit invitation_code when registrationCode is undefined, instead of passing invitation_code: undefined). Please update the implementation accordingly to avoid TS type errors and unintended JSON payloads.

Copilot uses AI. Check for mistakes.
Comment on lines 68 to 72
# Invitation codes
FRONTEND_LOGIN_CODE=/.*/
FRONTEND_REGISTRATION_CODE=/.*/
FRONTEND_DISABLE_LOGIN_CODE=/.*/
GLOBAL_DISABLE_LOGIN_CODE=/.*/
FRONTEND_DISABLE_REGISTRATION=/.*/

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GLOBAL_DISABLE_REGISTRATION_CODE is used in the frontend/backend to bypass/hide the registration code, but it is not present in this env template. This makes it easy to deploy a mismatched configuration. Add GLOBAL_DISABLE_REGISTRATION_CODE (and document its expected values) to this template so it can be configured consistently.

Copilot uses AI. Check for mistakes.
Comment on lines 151 to 155
"FRONTEND_LOGIN_CODE": base64_encode(login_code),
"FRONTEND_DISABLE_LOGIN_CODE": base64_encode(disable_login_code),
"GLOBAL_DISABLE_LOGIN_CODE": base64_encode(disable_login_code),
"FRONTEND_REGISTRATION_CODE": base64_encode(registration_code),
"FRONTEND_ENABLE_CV_UPLOAD": base64_encode(enable_cv_upload or ""),
"FRONTEND_DISABLE_REGISTRATION": base64_encode(disable_registration),

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GLOBAL_DISABLE_REGISTRATION_CODE is read by the React app via envService, but this script does not read/emit it into env.js. As a result, deployments using prepare_frontend.py cannot actually toggle the feature. Read the env var and include it in frontend_env_json.

Copilot uses AI. Check for mistakes.
from abc import ABC
from typing import Optional

from app.app_config import get_application_config, ApplicationConfig

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_application_config is imported but never used in this module. Remove the unused import to avoid linter failures and keep the module minimal.

Suggested change
from app.app_config import get_application_config, ApplicationConfig
from app.app_config import ApplicationConfig

Copilot uses AI. Check for mistakes.

if can_bypass:
if invitation_code is not None:
self._logger.warning(f"Registration code bypass is enabled but an invitation code was provided. {invitation_code}")

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This warning logs the full invitation/registration code. If these codes are considered sensitive (they often function like secrets), logging them can leak usable codes into centralized logs. Consider masking/truncating the code (or logging only that a code was provided).

Suggested change
self._logger.warning(f"Registration code bypass is enabled but an invitation code was provided. {invitation_code}")
self._logger.warning(
"Registration code bypass is enabled but an invitation code was provided."
)

Copilot uses AI. Check for mistakes.
Comment thread iac/.env.example
Comment on lines 57 to 62
# Invitation codes
FRONTEND_LOGIN_CODE=<LOGIN_CODE>
FRONTEND_REGISTRATION_CODE=<REGISTRATION_CODE>
FRONTEND_DISABLE_LOGIN_CODE=<True/False>
GLOBAL_DISABLE_LOGIN_CODE=<True/False>
FRONTEND_DISABLE_REGISTRATION=<True/False>
FRONTEND_DISABLE_SOCIAL_AUTH=<True/False>

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.env.example was updated to rename FRONTEND_DISABLE_LOGIN_CODE, but it does not include the newly introduced GLOBAL_DISABLE_REGISTRATION_CODE. Add it here so local/dev setups can exercise the registration-code bypass behavior and stay aligned with backend configuration.

Copilot uses AI. Check for mistakes.
Comment on lines +39 to +40
const registrationCodeDisabled = getRegistrationCodeDisabled().toLowerCase() === "true";

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

registrationCodeDisabled is evaluated at module import time. This makes the value impossible to change/mocking unreliable in tests, and it also triggers getEnv(...) (which touches window) during import, which can break non-browser runtimes. Compute this inside the component (e.g., via useMemo/useState) rather than at top-level.

Copilot uses AI. Check for mistakes.
Comment on lines +32 to +36
export type CreateUserPreferencesSpec =
| (CreatePreferencesSpecBase & {
invitation_code: string;
})
| CreatePreferencesSpecBase;

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CreateUserPreferencesSpec currently models “invitation_code omitted” vs “invitation_code is a string”, but it does not allow invitation_code: undefined. Several call sites now naturally have string | undefined values. Consider changing this to invitation_code?: string (or ensure all call sites omit the property entirely when undefined) to avoid type errors and unintended JSON payloads.

Suggested change
export type CreateUserPreferencesSpec =
| (CreatePreferencesSpecBase & {
invitation_code: string;
})
| CreatePreferencesSpecBase;
export type CreateUserPreferencesSpec = CreatePreferencesSpecBase & {
invitation_code?: string;
};

Copilot uses AI. Check for mistakes.
Comment on lines +919 to +920
// THEN the register function should be called with empty string for invitation code
// (since registrationCode state defaults to "" and no applicationRegistrationCode is set)

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says the register function should be called with an empty string, but the assertion expects undefined. Update the comment to match the intended behavior (passing undefined when registration code is bypassed).

Suggested change
// THEN the register function should be called with empty string for invitation code
// (since registrationCode state defaults to "" and no applicationRegistrationCode is set)
// THEN the register function should be called with undefined for the invitation code
// (since registration code handling is bypassed and no applicationRegistrationCode is set)

Copilot uses AI. Check for mistakes.
Comment on lines +3 to +10
from abc import ABC
from typing import Optional

from app.app_config import get_application_config, ApplicationConfig
from app.invitations import UserInvitationRepository, InvitationType, UserInvitation


class UserPreferencesValidator(ABC):

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Module 'abc' is imported with both 'import' and 'import from'.

Suggested change
from abc import ABC
from typing import Optional
from app.app_config import get_application_config, ApplicationConfig
from app.invitations import UserInvitationRepository, InvitationType, UserInvitation
class UserPreferencesValidator(ABC):
from typing import Optional
from app.app_config import get_application_config, ApplicationConfig
from app.invitations import UserInvitationRepository, InvitationType, UserInvitation
class UserPreferencesValidator(abc.ABC):

Copilot uses AI. Check for mistakes.
@irumvanselme
irumvanselme force-pushed the sub-task/implement-configurable-login-registration-via-code-CORE-10 branch from 059dd97 to c0f4f89 Compare February 5, 2026 07:02
…lumi up]

- Rename `FROTEND_DISABLE_LOGIN_CODE` to `GLOBAL_DISABLE_LOGIN_CODE` which disables currently login code only on the frontend so that we prevent uncontrolled anonymous accounts.
- Introduce `GLOBAL_DISABLE_REGISTRATION_CODE,` which disables registration from both backend and frontend.
@irumvanselme
irumvanselme force-pushed the sub-task/implement-configurable-login-registration-via-code-CORE-10 branch from c0f4f89 to 215e5b4 Compare February 5, 2026 07:02
@irumvanselme
irumvanselme merged commit c3e2149 into main Feb 5, 2026
8 checks passed
@irumvanselme
irumvanselme deleted the sub-task/implement-configurable-login-registration-via-code-CORE-10 branch February 5, 2026 07:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants