mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	chore: remove private projects flag (#5743)
This commit is contained in:
		
							parent
							
								
									049c5b9afa
								
							
						
					
					
						commit
						dc0df235dd
					
				@ -14,7 +14,6 @@ const StyledDescription = styled(Typography)(({ theme }) => ({
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
export const CollaborationModeTooltip: FC = () => {
 | 
			
		||||
    const privateProjects = useUiFlag('privateProjects');
 | 
			
		||||
    return (
 | 
			
		||||
        <HelpIcon
 | 
			
		||||
            htmlTooltip
 | 
			
		||||
@ -33,19 +32,13 @@ export const CollaborationModeTooltip: FC = () => {
 | 
			
		||||
                            requests
 | 
			
		||||
                        </StyledDescription>
 | 
			
		||||
                    </Box>
 | 
			
		||||
                    <ConditionallyRender
 | 
			
		||||
                        condition={Boolean(privateProjects)}
 | 
			
		||||
                        show={
 | 
			
		||||
                            <Box sx={{ mt: 2 }}>
 | 
			
		||||
                                <StyledTitle>private: </StyledTitle>
 | 
			
		||||
                                <StyledDescription>
 | 
			
		||||
                                    Only admins, editors and project members can
 | 
			
		||||
                                    see and access the project and associated
 | 
			
		||||
                                    feature toggles
 | 
			
		||||
                                </StyledDescription>
 | 
			
		||||
                            </Box>
 | 
			
		||||
                        }
 | 
			
		||||
                    />
 | 
			
		||||
                    <Box sx={{ mt: 2 }}>
 | 
			
		||||
                        <StyledTitle>private: </StyledTitle>
 | 
			
		||||
                        <StyledDescription>
 | 
			
		||||
                            Only admins, editors and project members can see and
 | 
			
		||||
                            access the project and associated feature toggles
 | 
			
		||||
                        </StyledDescription>
 | 
			
		||||
                    </Box>
 | 
			
		||||
                </>
 | 
			
		||||
            }
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
@ -133,23 +133,15 @@ const ProjectEnterpriseSettingsForm: React.FC<IProjectEnterpriseSettingsForm> =
 | 
			
		||||
        setFeatureNamingDescription,
 | 
			
		||||
        setProjectMode,
 | 
			
		||||
        errors,
 | 
			
		||||
        clearErrors,
 | 
			
		||||
    }) => {
 | 
			
		||||
        const privateProjects = useUiFlag('privateProjects');
 | 
			
		||||
 | 
			
		||||
        const { setPreviousPattern, trackPattern } =
 | 
			
		||||
            useFeatureNamePatternTracking();
 | 
			
		||||
 | 
			
		||||
        const projectModeOptions = privateProjects
 | 
			
		||||
            ? [
 | 
			
		||||
                  { key: 'open', label: 'open' },
 | 
			
		||||
                  { key: 'protected', label: 'protected' },
 | 
			
		||||
                  { key: 'private', label: 'private' },
 | 
			
		||||
              ]
 | 
			
		||||
            : [
 | 
			
		||||
                  { key: 'open', label: 'open' },
 | 
			
		||||
                  { key: 'protected', label: 'protected' },
 | 
			
		||||
              ];
 | 
			
		||||
        const projectModeOptions = [
 | 
			
		||||
            { key: 'open', label: 'open' },
 | 
			
		||||
            { key: 'protected', label: 'protected' },
 | 
			
		||||
            { key: 'private', label: 'private' },
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        useEffect(() => {
 | 
			
		||||
            setPreviousPattern(featureNamingPattern || '');
 | 
			
		||||
 | 
			
		||||
@ -103,18 +103,12 @@ const ProjectForm: React.FC<IProjectForm> = ({
 | 
			
		||||
    clearErrors,
 | 
			
		||||
}) => {
 | 
			
		||||
    const { isEnterprise } = useUiConfig();
 | 
			
		||||
    const privateProjects = useUiFlag('privateProjects');
 | 
			
		||||
 | 
			
		||||
    const projectModeOptions = privateProjects
 | 
			
		||||
        ? [
 | 
			
		||||
              { key: 'open', label: 'open' },
 | 
			
		||||
              { key: 'protected', label: 'protected' },
 | 
			
		||||
              { key: 'private', label: 'private' },
 | 
			
		||||
          ]
 | 
			
		||||
        : [
 | 
			
		||||
              { key: 'open', label: 'open' },
 | 
			
		||||
              { key: 'protected', label: 'protected' },
 | 
			
		||||
          ];
 | 
			
		||||
    const projectModeOptions = [
 | 
			
		||||
        { key: 'open', label: 'open' },
 | 
			
		||||
        { key: 'protected', label: 'protected' },
 | 
			
		||||
        { key: 'private', label: 'private' },
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <StyledForm
 | 
			
		||||
 | 
			
		||||
@ -62,7 +62,6 @@ export type UiFlags = {
 | 
			
		||||
    customRootRolesKillSwitch?: boolean;
 | 
			
		||||
    strategyVariant?: boolean;
 | 
			
		||||
    doraMetrics?: boolean;
 | 
			
		||||
    privateProjects?: boolean;
 | 
			
		||||
    dependentFeatures?: boolean;
 | 
			
		||||
    scheduledConfigurationChanges?: boolean;
 | 
			
		||||
    featureSearchAPI?: boolean;
 | 
			
		||||
 | 
			
		||||
@ -104,7 +104,6 @@ exports[`should create default config 1`] = `
 | 
			
		||||
      "migrationLock": true,
 | 
			
		||||
      "newStrategyConfiguration": false,
 | 
			
		||||
      "personalAccessTokensKillSwitch": false,
 | 
			
		||||
      "privateProjects": false,
 | 
			
		||||
      "proPlanAutoCharge": false,
 | 
			
		||||
      "responseTimeWithAppNameKillSwitch": false,
 | 
			
		||||
      "scheduledConfigurationChanges": false,
 | 
			
		||||
 | 
			
		||||
@ -1095,7 +1095,7 @@ class FeatureToggleService {
 | 
			
		||||
            archived,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        if (this.flagResolver.isEnabled('privateProjects') && userId) {
 | 
			
		||||
        if (userId) {
 | 
			
		||||
            const projectAccess =
 | 
			
		||||
                await this.privateProjectChecker.getUserAccessibleProjects(
 | 
			
		||||
                    userId,
 | 
			
		||||
@ -2053,20 +2053,15 @@ class FeatureToggleService {
 | 
			
		||||
    ): Promise<FeatureToggle[]> {
 | 
			
		||||
        const features = await this.featureToggleStore.getArchivedFeatures();
 | 
			
		||||
 | 
			
		||||
        if (this.flagResolver.isEnabled('privateProjects')) {
 | 
			
		||||
            const projectAccess =
 | 
			
		||||
                await this.privateProjectChecker.getUserAccessibleProjects(
 | 
			
		||||
                    userId,
 | 
			
		||||
                );
 | 
			
		||||
            if (projectAccess.mode === 'all') {
 | 
			
		||||
                return features;
 | 
			
		||||
            } else {
 | 
			
		||||
                return features.filter((f) =>
 | 
			
		||||
                    projectAccess.projects.includes(f.project),
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        const projectAccess =
 | 
			
		||||
            await this.privateProjectChecker.getUserAccessibleProjects(userId);
 | 
			
		||||
        if (projectAccess.mode === 'all') {
 | 
			
		||||
            return features;
 | 
			
		||||
        } else {
 | 
			
		||||
            return features.filter((f) =>
 | 
			
		||||
                projectAccess.projects.includes(f.project),
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        return features;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async getArchivedFeaturesByProjectId(
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,6 @@ beforeAll(async () => {
 | 
			
		||||
                    advancedPlayground: true,
 | 
			
		||||
                    strictSchemaValidation: true,
 | 
			
		||||
                    strategyVariant: true,
 | 
			
		||||
                    privateProjects: true,
 | 
			
		||||
                },
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
@ -102,20 +102,17 @@ export class PlaygroundService {
 | 
			
		||||
        const segments = await this.segmentService.getActive();
 | 
			
		||||
 | 
			
		||||
        let filteredProjects: typeof projects = projects;
 | 
			
		||||
        if (this.flagResolver.isEnabled('privateProjects')) {
 | 
			
		||||
            const projectAccess =
 | 
			
		||||
                await this.privateProjectChecker.getUserAccessibleProjects(
 | 
			
		||||
                    userId,
 | 
			
		||||
                );
 | 
			
		||||
            if (projectAccess.mode === 'all') {
 | 
			
		||||
                filteredProjects = projects;
 | 
			
		||||
            } else if (projects === ALL) {
 | 
			
		||||
                filteredProjects = projectAccess.projects;
 | 
			
		||||
            } else {
 | 
			
		||||
                filteredProjects = projects.filter((project) =>
 | 
			
		||||
                    projectAccess.projects.includes(project),
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        const projectAccess =
 | 
			
		||||
            await this.privateProjectChecker.getUserAccessibleProjects(userId);
 | 
			
		||||
        if (projectAccess.mode === 'all') {
 | 
			
		||||
            filteredProjects = projects;
 | 
			
		||||
        } else if (projects === ALL) {
 | 
			
		||||
            filteredProjects = projectAccess.projects;
 | 
			
		||||
        } else {
 | 
			
		||||
            filteredProjects = projects.filter((project) =>
 | 
			
		||||
                projectAccess.projects.includes(project),
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const environmentFeatures = await Promise.all(
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,10 @@
 | 
			
		||||
import { IPrivateProjectChecker } from './privateProjectCheckerType';
 | 
			
		||||
import { ProjectAccess } from './privateProjectStore';
 | 
			
		||||
import { ALL_PROJECT_ACCESS, ProjectAccess } from './privateProjectStore';
 | 
			
		||||
 | 
			
		||||
export class FakePrivateProjectChecker implements IPrivateProjectChecker {
 | 
			
		||||
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
    async getUserAccessibleProjects(userId: number): Promise<ProjectAccess> {
 | 
			
		||||
        throw new Error('Method not implemented.');
 | 
			
		||||
        return ALL_PROJECT_ACCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
 | 
			
		||||
@ -160,29 +160,24 @@ export default class ClientInstanceService {
 | 
			
		||||
    ): Promise<IClientApplication[]> {
 | 
			
		||||
        const applications =
 | 
			
		||||
            await this.clientApplicationsStore.getAppsForStrategy(query);
 | 
			
		||||
        if (this.flagResolver.isEnabled('privateProjects')) {
 | 
			
		||||
            const accessibleProjects =
 | 
			
		||||
                await this.privateProjectChecker.getUserAccessibleProjects(
 | 
			
		||||
                    userId,
 | 
			
		||||
                );
 | 
			
		||||
            if (accessibleProjects.mode === 'all') {
 | 
			
		||||
                return applications;
 | 
			
		||||
            } else {
 | 
			
		||||
                return applications.map((application) => {
 | 
			
		||||
                    return {
 | 
			
		||||
                        ...application,
 | 
			
		||||
                        usage: application.usage?.filter(
 | 
			
		||||
                            (usageItem) =>
 | 
			
		||||
                                usageItem.project === ALL_PROJECTS ||
 | 
			
		||||
                                accessibleProjects.projects.includes(
 | 
			
		||||
                                    usageItem.project,
 | 
			
		||||
                                ),
 | 
			
		||||
                        ),
 | 
			
		||||
                    };
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        const accessibleProjects =
 | 
			
		||||
            await this.privateProjectChecker.getUserAccessibleProjects(userId);
 | 
			
		||||
        if (accessibleProjects.mode === 'all') {
 | 
			
		||||
            return applications;
 | 
			
		||||
        } else {
 | 
			
		||||
            return applications.map((application) => {
 | 
			
		||||
                return {
 | 
			
		||||
                    ...application,
 | 
			
		||||
                    usage: application.usage?.filter(
 | 
			
		||||
                        (usageItem) =>
 | 
			
		||||
                            usageItem.project === ALL_PROJECTS ||
 | 
			
		||||
                            accessibleProjects.projects.includes(
 | 
			
		||||
                                usageItem.project,
 | 
			
		||||
                            ),
 | 
			
		||||
                    ),
 | 
			
		||||
                };
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        return applications;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async getApplication(appName: string): Promise<IApplication> {
 | 
			
		||||
 | 
			
		||||
@ -75,24 +75,17 @@ class ContextService {
 | 
			
		||||
    ): Promise<ContextFieldStrategiesSchema> {
 | 
			
		||||
        const strategies =
 | 
			
		||||
            await this.featureStrategiesStore.getStrategiesByContextField(name);
 | 
			
		||||
        if (this.flagResolver.isEnabled('privateProjects')) {
 | 
			
		||||
            const accessibleProjects =
 | 
			
		||||
                await this.privateProjectChecker.getUserAccessibleProjects(
 | 
			
		||||
                    userId,
 | 
			
		||||
                );
 | 
			
		||||
            if (accessibleProjects.mode === 'all') {
 | 
			
		||||
                return this.mapStrategies(strategies);
 | 
			
		||||
            } else {
 | 
			
		||||
                return this.mapStrategies(
 | 
			
		||||
                    strategies.filter((strategy) =>
 | 
			
		||||
                        accessibleProjects.projects.includes(
 | 
			
		||||
                            strategy.projectId,
 | 
			
		||||
                        ),
 | 
			
		||||
                    ),
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        const accessibleProjects =
 | 
			
		||||
            await this.privateProjectChecker.getUserAccessibleProjects(userId);
 | 
			
		||||
        if (accessibleProjects.mode === 'all') {
 | 
			
		||||
            return this.mapStrategies(strategies);
 | 
			
		||||
        } else {
 | 
			
		||||
            return this.mapStrategies(
 | 
			
		||||
                strategies.filter((strategy) =>
 | 
			
		||||
                    accessibleProjects.projects.includes(strategy.projectId),
 | 
			
		||||
                ),
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        return this.mapStrategies(strategies);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private mapStrategies(strategies: IFeatureStrategy[]) {
 | 
			
		||||
 | 
			
		||||
@ -180,7 +180,7 @@ export default class ProjectService {
 | 
			
		||||
            userId,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        if (this.flagResolver.isEnabled('privateProjects') && userId) {
 | 
			
		||||
        if (userId) {
 | 
			
		||||
            const projectAccess =
 | 
			
		||||
                await this.privateProjectChecker.getUserAccessibleProjects(
 | 
			
		||||
                    userId,
 | 
			
		||||
 | 
			
		||||
@ -96,24 +96,19 @@ export class SegmentService implements ISegmentService {
 | 
			
		||||
        userId: number,
 | 
			
		||||
    ): Promise<StrategiesUsingSegment> {
 | 
			
		||||
        const allStrategies = await this.getAllStrategies(id);
 | 
			
		||||
        if (this.flagResolver.isEnabled('privateProjects')) {
 | 
			
		||||
            const accessibleProjects =
 | 
			
		||||
                await this.privateProjectChecker.getUserAccessibleProjects(
 | 
			
		||||
                    userId,
 | 
			
		||||
                );
 | 
			
		||||
            if (accessibleProjects.mode === 'all') {
 | 
			
		||||
                return allStrategies;
 | 
			
		||||
            } else {
 | 
			
		||||
                const filter = (strategy) =>
 | 
			
		||||
                    accessibleProjects.projects.includes(strategy.projectId);
 | 
			
		||||
                return {
 | 
			
		||||
                    strategies: allStrategies.strategies.filter(filter),
 | 
			
		||||
                    changeRequestStrategies:
 | 
			
		||||
                        allStrategies.changeRequestStrategies.filter(filter),
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
        const accessibleProjects =
 | 
			
		||||
            await this.privateProjectChecker.getUserAccessibleProjects(userId);
 | 
			
		||||
        if (accessibleProjects.mode === 'all') {
 | 
			
		||||
            return allStrategies;
 | 
			
		||||
        } else {
 | 
			
		||||
            const filter = (strategy) =>
 | 
			
		||||
                accessibleProjects.projects.includes(strategy.projectId);
 | 
			
		||||
            return {
 | 
			
		||||
                strategies: allStrategies.strategies.filter(filter),
 | 
			
		||||
                changeRequestStrategies:
 | 
			
		||||
                    allStrategies.changeRequestStrategies.filter(filter),
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        return allStrategies;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async getAllStrategies(id: number): Promise<StrategiesUsingSegment> {
 | 
			
		||||
 | 
			
		||||
@ -23,7 +23,6 @@ export type IFlagKey =
 | 
			
		||||
    | 'advancedPlayground'
 | 
			
		||||
    | 'filterInvalidClientMetrics'
 | 
			
		||||
    | 'customRootRolesKillSwitch'
 | 
			
		||||
    | 'privateProjects'
 | 
			
		||||
    | 'disableMetrics'
 | 
			
		||||
    | 'featureSearchAPI'
 | 
			
		||||
    | 'featureSearchFrontend'
 | 
			
		||||
@ -112,10 +111,6 @@ const flags: IFlags = {
 | 
			
		||||
        process.env.UNLEASH_EXPERIMENTAL_CUSTOM_ROOT_ROLES_KILL_SWITCH,
 | 
			
		||||
        false,
 | 
			
		||||
    ),
 | 
			
		||||
    privateProjects: parseEnvVarBoolean(
 | 
			
		||||
        process.env.UNLEASH_EXPERIMENTAL_PRIVATE_PROJECTS,
 | 
			
		||||
        false,
 | 
			
		||||
    ),
 | 
			
		||||
    disableMetrics: parseEnvVarBoolean(
 | 
			
		||||
        process.env.UNLEASH_EXPERIMENTAL_DISABLE_METRICS,
 | 
			
		||||
        false,
 | 
			
		||||
 | 
			
		||||
@ -40,7 +40,6 @@ process.nextTick(async () => {
 | 
			
		||||
                        embedProxyFrontend: true,
 | 
			
		||||
                        anonymiseEventLog: false,
 | 
			
		||||
                        responseTimeWithAppNameKillSwitch: false,
 | 
			
		||||
                        privateProjects: true,
 | 
			
		||||
                        featureSearchAPI: true,
 | 
			
		||||
                        featureSearchFrontend: true,
 | 
			
		||||
                        stripClientHeadersOn304: true,
 | 
			
		||||
 | 
			
		||||
@ -10,13 +10,17 @@ let app: IUnleashTest;
 | 
			
		||||
 | 
			
		||||
beforeAll(async () => {
 | 
			
		||||
    db = await dbInit('context_api_serial', getLogger);
 | 
			
		||||
    app = await setupAppWithCustomConfig(db.stores, {
 | 
			
		||||
        experimental: {
 | 
			
		||||
            flags: {
 | 
			
		||||
                strictSchemaValidation: true,
 | 
			
		||||
    app = await setupAppWithCustomConfig(
 | 
			
		||||
        db.stores,
 | 
			
		||||
        {
 | 
			
		||||
            experimental: {
 | 
			
		||||
                flags: {
 | 
			
		||||
                    strictSchemaValidation: true,
 | 
			
		||||
                },
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    });
 | 
			
		||||
        db.rawDatabase,
 | 
			
		||||
    );
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
afterAll(async () => {
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ let db: ITestDb;
 | 
			
		||||
 | 
			
		||||
beforeAll(async () => {
 | 
			
		||||
    db = await dbInit('metrics_serial', getLogger, {});
 | 
			
		||||
    app = await setupAppWithCustomConfig(db.stores, {});
 | 
			
		||||
    app = await setupAppWithCustomConfig(db.stores, {}, db.rawDatabase);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
beforeEach(async () => {
 | 
			
		||||
 | 
			
		||||
@ -61,9 +61,6 @@ beforeAll(async () => {
 | 
			
		||||
    });
 | 
			
		||||
    const config = createTestConfig({
 | 
			
		||||
        getLogger,
 | 
			
		||||
        experimental: {
 | 
			
		||||
            flags: { privateProjects: true },
 | 
			
		||||
        },
 | 
			
		||||
    });
 | 
			
		||||
    eventService = new EventService(stores, config);
 | 
			
		||||
    accessService = createAccessService(db.rawDatabase, config);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user