Browse Source

Add knob to control user signup feature

Add knob "Disable User Signup" in Admin overview page
Add new permission to handle this knob, only admin has access
Add new admin property to store this knob config
Validate user signup against this config.
pull/1512/head
gobdevel 3 years ago
parent
commit
f5eee4b4dc
  1. 13
      apps/api/src/app/info/info.service.ts
  2. 18
      apps/api/src/app/user/user.controller.ts
  3. 6
      apps/api/src/app/user/user.service.ts
  4. 1
      apps/api/src/services/configuration.service.ts
  5. 1
      apps/api/src/services/interfaces/environment.interface.ts
  6. 16
      apps/client/src/app/components/admin-overview/admin-overview.component.ts
  7. 11
      apps/client/src/app/components/admin-overview/admin-overview.html
  8. 1
      libs/common/src/lib/config.ts
  9. 3
      libs/common/src/lib/permissions.ts

13
apps/api/src/app/info/info.service.ts

@ -11,6 +11,7 @@ import {
PROPERTY_SLACK_COMMUNITY_USERS,
PROPERTY_STRIPE_CONFIG,
PROPERTY_SYSTEM_MESSAGE,
PROPERTY_DISABLE_USER_SIGNUP,
ghostfolioFearAndGreedIndexDataSource
} from '@ghostfolio/common/config';
import {
@ -103,6 +104,18 @@ export class InfoService {
)) as string;
}
if (this.configurationService.get('ENABLE_FEATURE_USER_SIGNUP_CONTROL')) {
const isUserSignupDisabled = (await this.propertyService.getByKey(
PROPERTY_DISABLE_USER_SIGNUP
)) as boolean;
if (!isUserSignupDisabled) {
globalPermissions.push(permissions.createUserAccount);
}
} else { // By default enabled
globalPermissions.push(permissions.createUserAccount);
}
return {
...info,
globalPermissions,

18
apps/api/src/app/user/user.controller.ts

@ -1,6 +1,9 @@
import { ConfigurationService } from '@ghostfolio/api/services/configuration.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import { PROPERTY_IS_READ_ONLY_MODE } from '@ghostfolio/common/config';
import {
PROPERTY_IS_READ_ONLY_MODE,
PROPERTY_DISABLE_USER_SIGNUP
} from '@ghostfolio/common/config';
import { User, UserSettings } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import type { RequestWithUser } from '@ghostfolio/common/types';
@ -82,6 +85,19 @@ export class UserController {
}
}
if (this.configurationService.get('ENABLE_FEATURE_USER_SIGNUP_CONTROL')) {
const isUserSignupDisabled = (await this.propertyService.getByKey(
PROPERTY_DISABLE_USER_SIGNUP
)) as boolean;
if (isUserSignupDisabled) {
throw new HttpException(
getReasonPhrase(StatusCodes.FORBIDDEN),
StatusCodes.FORBIDDEN
);
}
}
const hasAdmin = await this.userService.hasAdmin();
const { accessToken, id, role } = await this.userService.createUser({

6
apps/api/src/app/user/user.service.ts

@ -185,6 +185,12 @@ export class UserService {
}
}
if (this.configurationService.get('ENABLE_FEATURE_USER_SIGNUP_CONTROL')) {
if (hasRole(user, Role.ADMIN)) {
currentPermissions.push(permissions.toggleUserSignupMode);
}
}
user.Account = sortBy(user.Account, (account) => {
return account.name;
});

1
apps/api/src/services/configuration.service.ts

@ -30,6 +30,7 @@ export class ConfigurationService {
ENABLE_FEATURE_STATISTICS: bool({ default: false }),
ENABLE_FEATURE_SUBSCRIPTION: bool({ default: false }),
ENABLE_FEATURE_SYSTEM_MESSAGE: bool({ default: false }),
ENABLE_FEATURE_USER_SIGNUP_CONTROL: bool({ default: false }),
EOD_HISTORICAL_DATA_API_KEY: str({ default: '' }),
GOOGLE_CLIENT_ID: str({ default: 'dummyClientId' }),
GOOGLE_SECRET: str({ default: 'dummySecret' }),

1
apps/api/src/services/interfaces/environment.interface.ts

@ -16,6 +16,7 @@ export interface Environment extends CleanedEnvAccessors {
ENABLE_FEATURE_STATISTICS: boolean;
ENABLE_FEATURE_SUBSCRIPTION: boolean;
ENABLE_FEATURE_SYSTEM_MESSAGE: boolean;
ENABLE_FEATURE_USER_SIGNUP_CONTROL: boolean;
EOD_HISTORICAL_DATA_API_KEY: string;
GOOGLE_CLIENT_ID: string;
GOOGLE_SECRET: string;

16
apps/client/src/app/components/admin-overview/admin-overview.component.ts

@ -7,7 +7,8 @@ import {
PROPERTY_COUPONS,
PROPERTY_CURRENCIES,
PROPERTY_IS_READ_ONLY_MODE,
PROPERTY_SYSTEM_MESSAGE
PROPERTY_SYSTEM_MESSAGE,
PROPERTY_DISABLE_USER_SIGNUP
} from '@ghostfolio/common/config';
import { Coupon, InfoItem, User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
@ -34,6 +35,7 @@ export class AdminOverviewComponent implements OnDestroy, OnInit {
public hasPermissionForSubscription: boolean;
public hasPermissionForSystemMessage: boolean;
public hasPermissionToToggleReadOnlyMode: boolean;
public hasPermissionToToggleUserSignupMode: boolean;
public info: InfoItem;
public transactionCount: number;
public userCount: number;
@ -69,6 +71,11 @@ export class AdminOverviewComponent implements OnDestroy, OnInit {
this.user.permissions,
permissions.toggleReadOnlyMode
);
this.hasPermissionToToggleUserSignupMode = hasPermission(
this.user.permissions,
permissions.toggleUserSignupMode
);
}
});
}
@ -167,6 +174,13 @@ export class AdminOverviewComponent implements OnDestroy, OnInit {
});
}
public onEnableUserSignupModeChange(aEvent: MatSlideToggleChange) {
this.putAdminSetting({
key: PROPERTY_DISABLE_USER_SIGNUP,
value: aEvent.checked ? true : undefined
});
}
public onSetSystemMessage() {
const systemMessage = prompt($localize`Please set your system message:`);

11
apps/client/src/app/components/admin-overview/admin-overview.html

@ -119,6 +119,17 @@
></mat-slide-toggle>
</div>
</div>
<div class="d-flex my-3">
<div class="w-50" i18n> Disable User Signup </div>
<div class="w-50">
<mat-slide-toggle
color="primary"
[disabled]="!hasPermissionToToggleUserSignupMode"
[checked]="!info.globalPermissions.includes('createUserAccount')"
(change)="onEnableUserSignupModeChange($event)"
></mat-slide-toggle>
</div>
</div>
<div
*ngIf="hasPermissionForSubscription"
class="d-flex my-3 subscription"

1
libs/common/src/lib/config.ts

@ -77,6 +77,7 @@ export const PROPERTY_IS_READ_ONLY_MODE = 'IS_READ_ONLY_MODE';
export const PROPERTY_SLACK_COMMUNITY_USERS = 'SLACK_COMMUNITY_USERS';
export const PROPERTY_STRIPE_CONFIG = 'STRIPE_CONFIG';
export const PROPERTY_SYSTEM_MESSAGE = 'SYSTEM_MESSAGE';
export const PROPERTY_DISABLE_USER_SIGNUP = 'PROPERTY_DISABLE_USER_SIGNUP';
export const QUEUE_JOB_STATUS_LIST = <JobStatus[]>[
'active',

3
libs/common/src/lib/permissions.ts

@ -26,7 +26,8 @@ export const permissions = {
updateAuthDevice: 'updateAuthDevice',
updateOrder: 'updateOrder',
updateUserSettings: 'updateUserSettings',
updateViewMode: 'updateViewMode'
updateViewMode: 'updateViewMode',
toggleUserSignupMode: 'toggleUserSignupMode'
};
export function getPermissions(aRole: Role): string[] {

Loading…
Cancel
Save