diff --git a/src/portal/src/app/account/account-settings/account-settings-modal-service.service.ts b/src/portal/src/app/account/account-settings/account-settings-modal-service.service.ts index 6f9eea303..2a497248a 100644 --- a/src/portal/src/app/account/account-settings/account-settings-modal-service.service.ts +++ b/src/portal/src/app/account/account-settings/account-settings-modal-service.service.ts @@ -10,8 +10,8 @@ import { throwError as observableThrowError, Observable } from 'rxjs'; export class AccountSettingsModalService { constructor(private http: HttpClient) { } - generateCli(userId): Observable { - return this.http.post(`/api/users/${userId}/gen_cli_secret`, {}).pipe( map(response => response) + saveNewCli(userId, secretObj): Observable { + return this.http.put(`/api/users/${userId}/cli_secret`, secretObj).pipe( map(response => response) , catchError(error => observableThrowError(error))); } } diff --git a/src/portal/src/app/account/account-settings/account-settings-modal.component.html b/src/portal/src/app/account/account-settings/account-settings-modal.component.html index 8898f9c6a..1b6a3d9fd 100644 --- a/src/portal/src/app/account/account-settings/account-settings-modal.component.html +++ b/src/portal/src/app/account/account-settings/account-settings-modal.component.html @@ -4,10 +4,11 @@
- +
- +
- +
- @@ -38,8 +41,10 @@
- {{'TOOLTIP.FULL_NAME' | translate}} @@ -47,14 +52,14 @@ - + {{'TOOLTIP.COMMENT' | translate}} -
+
- - +
- +
-
···
+
···
+
+ + + + + + \ No newline at end of file diff --git a/src/portal/src/app/account/account-settings/account-settings-modal.component.scss b/src/portal/src/app/account/account-settings/account-settings-modal.component.scss index 58c42d575..b5a3adf90 100644 --- a/src/portal/src/app/account/account-settings/account-settings-modal.component.scss +++ b/src/portal/src/app/account/account-settings/account-settings-modal.component.scss @@ -5,6 +5,7 @@ clr-modal { .rename-tool { .btn { margin-right: 6px; + margin-left: 5px; padding-left: 3px; padding-right: 3px; } @@ -18,10 +19,15 @@ clr-modal { align-items: center; .reset-cli { height: 30px; + padding-top: 8px; } .btn-padding-less { padding-left: 5px; padding-right: 5px; + margin-left: 5px; + } + .input-cli { + width: 9.5rem; } } .hidden-generate-cli { @@ -32,7 +38,12 @@ clr-modal { line-height: 30px; } } - +.reset-cli-form { + width: 19.5rem; +} .display-flex { display: flex; +} +.set-btns { + display: flex; } \ No newline at end of file diff --git a/src/portal/src/app/account/account-settings/account-settings-modal.component.ts b/src/portal/src/app/account/account-settings/account-settings-modal.component.ts index 4386a2421..7737307cc 100644 --- a/src/portal/src/app/account/account-settings/account-settings-modal.component.ts +++ b/src/portal/src/app/account/account-settings/account-settings-modal.component.ts @@ -29,6 +29,8 @@ import { ConfirmationTargets, ConfirmationButtons } from "../../shared/shared.const"; +import { randomWord } from '../../shared/shared.utils'; +import { ResetSecret } from './account'; @Component({ selector: "account-settings-modal", templateUrl: "account-settings-modal.component.html", @@ -49,13 +51,15 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked { originAdminName = "admin"; newAdminName = "admin@harbor.local"; renameConfirmation = false; -// confirmRename = false; + showSecretDetail = false; + resetForms = new ResetSecret(); showGenerateCli: boolean = false; @ViewChild("confirmationDialog", {static: false}) confirmationDialogComponent: ConfirmationDialogComponent; accountFormRef: NgForm; @ViewChild("accountSettingsFrom", {static: true}) accountForm: NgForm; + @ViewChild("resetSecretFrom", {static: true}) resetSecretFrom: NgForm; @ViewChild(InlineAlertComponent, {static: false}) inlineAlert: InlineAlertComponent; @ViewChild("copyInput", {static: false}) copyInput: CopyInputComponent; @@ -350,13 +354,26 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked { showGenerateCliFn() { this.showGenerateCli = !this.showGenerateCli; } - confirmGenerate(confirmData): void { - let userId = confirmData.data; - this.accountSettingsService.generateCli(userId).subscribe(cliSecret => { - this.account.oidc_user_meta.secret = cliSecret.secret; + confirmGenerate(event): void { + this.account.oidc_user_meta.secret = randomWord(9); + this.resetCliSecret(this.account.oidc_user_meta.secret); + } + + resetCliSecret(secret) { + let userId = this.account.user_id; + this.accountSettingsService.saveNewCli(userId, {secret: secret}).subscribe(cliSecret => { + this.account.oidc_user_meta.secret = secret; + this.closeReset(); this.inlineAlert.showInlineSuccess({message: 'PROFILE.GENERATE_SUCCESS'}); }, error => { this.inlineAlert.showInlineError({message: 'PROFILE.GENERATE_ERROR'}); }); } + disableChangeCliSecret() { + return this.resetSecretFrom.invalid || (this.resetSecretFrom.value.input_secret !== this.resetSecretFrom.value.confirm_secret); + } + closeReset() { + this.showSecretDetail = false; + this.resetSecretFrom.resetForm(new ResetSecret()); + } } diff --git a/src/portal/src/app/account/account-settings/account.ts b/src/portal/src/app/account/account-settings/account.ts new file mode 100644 index 000000000..19a6422ca --- /dev/null +++ b/src/portal/src/app/account/account-settings/account.ts @@ -0,0 +1,8 @@ +export class ResetSecret { + input_secret: string; + confirm_secret: string; + constructor() { + this.confirm_secret = ""; + this.input_secret = ""; + } +} diff --git a/src/portal/src/app/shared/shared.utils.ts b/src/portal/src/app/shared/shared.utils.ts index 1a648dc0c..b220cc65d 100644 --- a/src/portal/src/app/shared/shared.utils.ts +++ b/src/portal/src/app/shared/shared.utils.ts @@ -75,4 +75,39 @@ export const maintainUrlQueryParmas = function (uri: string, key: string, value: } } }; +/** + * the password or secret must longer than 8 chars with at least 1 uppercase letter, 1 lowercase letter and 1 number + * @param randomFlag + * @param min + * @param max + * @returns {string} + */ + + export function randomWord(max) { + let str = ""; + + let contentArray = [['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], + ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l' + , 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x' + , 'y', 'z'], + ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' + , 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']]; + for (let i = 0; i < max; i++) { + let randomNumber = getRandomInt(contentArray.length); + str += contentArray[randomNumber][getRandomInt(contentArray[randomNumber].length)]; + } + if (!str.match(/\d+/g)) { + str += contentArray[0][getRandomInt(contentArray[0].length)]; + } + if (!str.match(/[a-z]+/g)) { + str += contentArray[1][getRandomInt(contentArray[1].length)]; + } + if (!str.match(/[A-Z]+/g)) { + str += contentArray[1][getRandomInt(contentArray[1].length)]; + } + return str; + } + function getRandomInt(max) { + return Math.floor(Math.random() * Math.floor(max)); + } diff --git a/src/portal/src/i18n/lang/en-us-lang.json b/src/portal/src/i18n/lang/en-us-lang.json index 260e7ba4b..bc047fbf0 100644 --- a/src/portal/src/i18n/lang/en-us-lang.json +++ b/src/portal/src/i18n/lang/en-us-lang.json @@ -99,7 +99,8 @@ "OIDC_SCOPE": "The scope sent to OIDC server during authentication. It has to contain “openid”, and “offline_access”. If you are using google, please remove “offline_access” from this field.", "OIDC_VERIFYCERT": "Uncheck this box if your OIDC server is hosted via self-signed certificate.", "OIDC_GROUP_CLAIM": "The name of Claim in the ID token whose value is the list of group names.", - "OIDC_GROUP_CLAIM_WARNING": "It can only contain letters, numbers, underscores, and the input length is no more than 256 characters." + "OIDC_GROUP_CLAIM_WARNING": "It can only contain letters, numbers, underscores, and the input length is no more than 256 characters.", + "NEW_SECRET": "The secret must longer than 8 chars with at least 1 uppercase letter, 1 lowercase letter and 1 number" }, "PLACEHOLDER": { "CURRENT_PWD": "Enter current password", @@ -128,8 +129,11 @@ "COPY_SUCCESS": "copy success", "COPY_ERROR": "copy failed", "ADMIN_CIL_SECRET_BUTTON": "GENERATE SECRET", - "GENERATE_SUCCESS": "generate CLI secret success", - "GENERATE_ERROR": "generate CLI secret failed", + "ADMIN_CIL_SECRET_RESET_BUTTON": "Upload Your Own Secret", + "NEW_SECRET": "Secret", + "CONFIRM_SECRET": "Re-enter Secret", + "GENERATE_SUCCESS": "Cli secret setting is successful", + "GENERATE_ERROR": "Cli secret setting is failed", "CONFIRM_TITLE_CLI_GENERATE": "Are you sure you can regenerate secret?", "CONFIRM_BODY_CLI_GENERATE": "If you regenerate cli secret, the old cli secret will be discarded" }, diff --git a/src/portal/src/i18n/lang/es-es-lang.json b/src/portal/src/i18n/lang/es-es-lang.json index bdff7bba4..c796ca1cf 100644 --- a/src/portal/src/i18n/lang/es-es-lang.json +++ b/src/portal/src/i18n/lang/es-es-lang.json @@ -99,7 +99,8 @@ "OIDC_SCOPE": "El ámbito de aplicación enviada a OIDC Server durante la autenticación.Tiene que contener 'Openid', y 'offline_access'.Si usted esta usando Google, por favor quitar 'offline_access' de este campo", "OIDC_VERIFYCERT": "Desmarque esta casilla si tu OIDC servidor está alojado a través de certificado autofirmado.", "OIDC_GROUP_CLAIM": "The name of Claim in the ID token whose value is the list of group names.", - "OIDC_GROUP_CLAIM_WARNING": "It can only contain letters, numbers, underscores, and the input length is no more than 256 characters." + "OIDC_GROUP_CLAIM_WARNING": "It can only contain letters, numbers, underscores, and the input length is no more than 256 characters.", + "NEW_SECRET": "The secret must longer than 8 chars with at least 1 uppercase letter, 1 lowercase letter and 1 number." }, "PLACEHOLDER": { "CURRENT_PWD": "Introduzca la contraseña actual", @@ -128,8 +129,11 @@ "COPY_SUCCESS": "Copiar el éxito", "COPY_ERROR": "Copia no", "ADMIN_CIL_SECRET_BUTTON": "GENERATE SECRET", - "GENERATE_SUCCESS": "generate CLI secret success", - "GENERATE_ERROR": "generate CLI secret failed", + "ADMIN_CIL_SECRET_RESET_BUTTON": "Upload Your Own Secret", + "NEW_SECRET": "Secret", + "CONFIRM_SECRET": "Re-enter Secret", + "GENERATE_SUCCESS": "Cli secret setting is successful", + "GENERATE_ERROR": "Cli secret setting is failed", "CONFIRM_TITLE_CLI_GENERATE": "Are you sure you can regenerate secret?", "CONFIRM_BODY_CLI_GENERATE": "If you regenerate cli secret, the old cli secret will be discarded" }, diff --git a/src/portal/src/i18n/lang/fr-fr-lang.json b/src/portal/src/i18n/lang/fr-fr-lang.json index 632544f29..aab767890 100644 --- a/src/portal/src/i18n/lang/fr-fr-lang.json +++ b/src/portal/src/i18n/lang/fr-fr-lang.json @@ -94,7 +94,8 @@ "OIDC_SCOPE": "le champ envoyés au serveur au cours oidc l'authentification.il doit contenir 'openid', et 'offline_access'.si vous utilisez google, veuillez supprimer 'offline_access' dans ce domaine", "OIDC_VERIFYCERT": "décocher cette case si votre oidc serveur est accueilli par auto - certificat signé.", "OIDC_GROUP_CLAIM": "The name of Claim in the ID token whose value is the list of group names.", - "OIDC_GROUP_CLAIM_WARNING": "It can only contain letters, numbers, underscores, and the input length is no more than 256 characters." + "OIDC_GROUP_CLAIM_WARNING": "It can only contain letters, numbers, underscores, and the input length is no more than 256 characters.", + "NEW_SECRET": "The secret must longer than 8 chars with at least 1 uppercase letter, 1 lowercase letter and 1 number." }, "PLACEHOLDER": { "CURRENT_PWD": "Entrez le mot de passe actuel", @@ -123,8 +124,11 @@ "COPY_SUCCESS": "copie de succès", "COPY_ERROR": "copie a échoué", "ADMIN_CIL_SECRET_BUTTON": "GENERATE SECRET", - "GENERATE_SUCCESS": "generate CLI secret success", - "GENERATE_ERROR": "generate CLI secret failed", + "ADMIN_CIL_SECRET_RESET_BUTTON": "Upload Your Own Secret", + "NEW_SECRET": "Secret", + "CONFIRM_SECRET": "Re-enter Secret", + "GENERATE_SUCCESS": "Cli secret setting is successful", + "GENERATE_ERROR": "Cli secret setting is failed", "CONFIRM_TITLE_CLI_GENERATE": "Are you sure you can regenerate secret?", "CONFIRM_BODY_CLI_GENERATE": "If you regenerate cli secret, the old cli secret will be discarded" }, diff --git a/src/portal/src/i18n/lang/pt-br-lang.json b/src/portal/src/i18n/lang/pt-br-lang.json index e1f357268..fe2d9a868 100644 --- a/src/portal/src/i18n/lang/pt-br-lang.json +++ b/src/portal/src/i18n/lang/pt-br-lang.json @@ -97,7 +97,8 @@ "OIDC_SCOPE": "O âmbito de aplicação enviada Ao servidor oidc Durante a autenticação.TEM que conter 'openid' e 'offline_access'.Se você está usando o Google, por favor remova 'offline_access' desse Campo.", "OIDC_VERIFYCERT": "Desmarque esta opção se o SEU servidor está hospedado oidc via self - signed certificate.", "OIDC_GROUP_CLAIM": "The name of Claim in the ID token whose value is the list of group names.", - "OIDC_GROUP_CLAIM_WARNING": "It can only contain letters, numbers, underscores, and the input length is no more than 256 characters." + "OIDC_GROUP_CLAIM_WARNING": "It can only contain letters, numbers, underscores, and the input length is no more than 256 characters.", + "NEW_SECRET": "The secret must longer than 8 chars with at least 1 uppercase letter, 1 lowercase letter and 1 number." }, "PLACEHOLDER": { "CURRENT_PWD": "Insira a senha atual", @@ -126,8 +127,11 @@ "COPY_SUCCESS": "SUCESSO de cópia", "COPY_ERROR": "Cópia falhou", "ADMIN_CIL_SECRET_BUTTON": "GENERATE SECRET", - "GENERATE_SUCCESS": "generate CLI secret success", - "GENERATE_ERROR": "generate CLI secret failed", + "ADMIN_CIL_SECRET_RESET_BUTTON": "Upload Your Own Secret", + "NEW_SECRET": "Secret", + "CONFIRM_SECRET": "Re-enter Secret", + "GENERATE_SUCCESS": "Cli secret setting is successful", + "GENERATE_ERROR": "Cli secret setting is failed", "CONFIRM_TITLE_CLI_GENERATE": "Are you sure you can regenerate secret?", "CONFIRM_BODY_CLI_GENERATE": "If you regenerate cli secret, the old cli secret will be discarded" }, diff --git a/src/portal/src/i18n/lang/tr-tr-lang.json b/src/portal/src/i18n/lang/tr-tr-lang.json index 13ce579c1..b89c4edc4 100644 --- a/src/portal/src/i18n/lang/tr-tr-lang.json +++ b/src/portal/src/i18n/lang/tr-tr-lang.json @@ -99,7 +99,8 @@ "OIDC_SCOPE": "Kapsam, kimlik doğrulama sırasında OIDC sunucusuna gönderildi. “Openid” ve “offline_access” içermelidir. Google kullanıyorsanız, lütfen “offline_access“'i bu alandan kaldırın.", "OIDC_VERIFYCERT": "OIDC sunucunuz kendinden imzalı sertifika ile barındırılıyorsa bu kutunun işaretini kaldırın.", "OIDC_GROUP_CLAIM": "The name of Claim in the ID token whose value is the list of group names.", - "OIDC_GROUP_CLAIM_WARNING": "It can only contain letters, numbers, underscores, and the input length is no more than 256 characters." + "OIDC_GROUP_CLAIM_WARNING": "It can only contain letters, numbers, underscores, and the input length is no more than 256 characters.", + "NEW_SECRET": "The secret must longer than 8 chars with at least 1 uppercase letter, 1 lowercase letter and 1 number." }, "PLACEHOLDER": { "CURRENT_PWD": "Güncel şifrenizi giriniz", @@ -128,8 +129,11 @@ "COPY_SUCCESS": "kopyalama başarılı", "COPY_ERROR": "kopyalama başarısız", "ADMIN_CIL_SECRET_BUTTON": "ŞİFRE OLUŞTUR", - "GENERATE_SUCCESS": "CLI şifresi oluşturma başarılı", - "GENERATE_ERROR": "CLI şifresi oluşturma başarısız", + "ADMIN_CIL_SECRET_RESET_BUTTON": "Upload Your Own Secret", + "NEW_SECRET": "Secret", + "CONFIRM_SECRET": "Re-enter Secret", + "GENERATE_SUCCESS": "Cli secret setting is successful", + "GENERATE_ERROR": "Cli secret setting is failed", "CONFIRM_TITLE_CLI_GENERATE": "Şifreyi yeniden oluşturabileceğine emin misin?", "CONFIRM_BODY_CLI_GENERATE": "Eğer cli şifresini yeniden oluşturursanız, eski cli şifresi atılır" }, diff --git a/src/portal/src/i18n/lang/zh-cn-lang.json b/src/portal/src/i18n/lang/zh-cn-lang.json index 6234396e6..de391055e 100644 --- a/src/portal/src/i18n/lang/zh-cn-lang.json +++ b/src/portal/src/i18n/lang/zh-cn-lang.json @@ -98,7 +98,8 @@ "OIDC_SCOPE": "在身份验证期间发送到OIDC服务器的scope。它必须包含“openid”和“offline_access”。如果您使用Google,请从此字段中删除“脱机访问”。", "OIDC_VERIFYCERT": "如果您的OIDC服务器是通过自签名证书托管的,请取消选中此框。", "OIDC_GROUP_CLAIM": "ID和token中的Claim名称,在组的名称列表中。", - "OIDC_GROUP_CLAIM_WARNING": "它只能包含字母、数字、下划线,且输入长度不超过256字符。" + "OIDC_GROUP_CLAIM_WARNING": "它只能包含字母、数字、下划线,且输入长度不超过256字符。", + "NEW_SECRET": "Cli secret 必须超过8个字符,并至少包含1个大写字母,1个小写字母和1个数字。" }, "PLACEHOLDER": { "CURRENT_PWD": "输入当前密码", @@ -127,8 +128,11 @@ "COPY_SUCCESS": "复制成功", "COPY_ERROR": "复制失败", "ADMIN_CIL_SECRET_BUTTON": "生成新的CLI密码", - "GENERATE_SUCCESS": "成功生成新的CLI密码", - "GENERATE_ERROR": "生成新的CLI密码失败", + "ADMIN_CIL_SECRET_RESET_BUTTON": "输入你自己的CLI密码", + "NEW_SECRET": "密码", + "CONFIRM_SECRET": "重复出入密码", + "GENERATE_SUCCESS": "成功设置新的CLI密码", + "GENERATE_ERROR": "设置新的CLI密码失败", "CONFIRM_TITLE_CLI_GENERATE": "您确定需要重新生成cli secret吗?", "CONFIRM_BODY_CLI_GENERATE": "如果您重新生成cli secret,那么旧的cli secret将会被弃用" },