• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { WidthPercent } from '../common/util/ConfigData';
17import HeadComponent from '../common/component/headComponent';
18import CmFaPresenter from '../presenter/CmFaPresenter';
19import { GlobalContext } from '../common/GlobalContext';
20import ComponentConfig from '../common/component/ComponentConfig';
21import router from '@ohos.router';
22import { CustomContentDialog } from '@ohos.arkui.advanced.Dialog';
23import checkUserAuthModel from '../model/CheckUserAuthModel';
24import { NavEntryKey } from '../common/NavEntryKey';
25import picker from '@ohos.file.picker';
26import FileIoModel from '../model/FileIoModel';
27import CmInstallPresenter from '../presenter/CmInstallPresenter';
28import { BusinessError } from '@ohos.base';
29import { RouterFileVo } from '../model/CertManagerVo/RouterInfoVo';
30import { CredPwdInputParam } from './detail/CredPwdInputPage';
31import { SheetParam } from '../common/util/SheetParam';
32import FilterParams from '../common/constants/FileFilterParams';
33import { UIContext } from '@kit.ArkUI';
34import { common } from '@kit.AbilityKit';
35
36const COPIES_NUM: number = 12;
37
38const TAG: string = 'CertInstallFromStorage: ';
39
40@Entry
41@Component
42export struct CertInstallFromStorage {
43  @State columnMargin: string = '12vp';
44  @State mFaPresenter: CmFaPresenter = CmFaPresenter.getInstance();
45  @State installCertFlag: boolean = false;
46  private context: Context = getContext(this);
47
48  isStartBySheetFirst: boolean = false;
49  isStartBySheet: boolean = false;
50  selected?: (path: string, param?: Object) => void;
51  @Prop sheetParam: SheetParam;
52  @State private headRectHeight: number = 64;
53  @State private headRectHeightReal: number = 0;
54  private scroller: Scroller = new Scroller();
55  @State private scrollerHeight: number = 0;
56
57  @Styles normalStyle() {
58    .backgroundColor($r('sys.color.ohos_id_color_card_bg'))
59    .borderRadius($r('app.float.user_list_divider_borderRadius_value'))
60  };
61  @Styles pressedStyle() {
62    .backgroundColor($r('sys.color.ohos_id_color_click_effect'))
63    .borderRadius($r('app.float.user_list_divider_borderRadius_value'))
64  };
65
66  rootCertificateDialog: CustomDialogController = new CustomDialogController({
67    alignment: DialogAlignment.Center,
68    builder: CustomContentDialog({
69      contentBuilder: () => {
70        this.rootCertificateContent();
71      },
72      contentAreaPadding: { right: $r('app.float.wh_value_0') },
73      buttons: [
74        {
75          value: $r('app.string.root_certificate_cancel'),
76          buttonStyle: ButtonStyleMode.TEXTUAL,
77          action: () => {
78          }
79        },
80        {
81          value: $r('app.string.root_certificate_continue'),
82          buttonStyle: ButtonStyleMode.TEXTUAL,
83          action: () => {
84            this.installCertFlag = true;
85            this.checkUserAuth();
86          }
87        }
88      ]
89    })
90  })
91
92  @Builder
93  rootCertificateContent(): void {
94    Column() {
95      Text($r('app.string.root_certificate'))
96        .height($r('app.float.wh_value_56'))
97        .fontSize($r('sys.float.ohos_id_text_size_dialog_tittle'))
98        .fontColor($r('sys.color.ohos_id_color_text_primary'))
99        .fontWeight(FontWeight.Medium)
100        .margin({
101          left: $r('app.float.wh_value_24'),
102          right: $r('app.float.wh_value_24')
103        })
104        .alignSelf(ItemAlign.Start)
105
106      Text($r('app.string.root_certificate_message'))
107        .fontSize($r('sys.float.ohos_id_text_size_body1'))
108        .fontWeight(FontWeight.Regular)
109        .fontColor($r('sys.color.ohos_id_color_primary'))
110        .margin({
111          left: $r('app.float.wh_value_24'),
112          right: $r('app.float.wh_value_24')
113        })
114        .alignSelf(ItemAlign.Start)
115    }
116    .width(WidthPercent.WH_100_100)
117    .borderRadius($r('app.float.user_list_divider_borderRadius_value'))
118    .backgroundColor($r('sys.color.ohos_id_color_dialog_bg'))
119  }
120
121  checkUserAuth() {
122    let titleStr = getContext().resourceManager.getStringSync($r('app.string.Identity_Authentication'));
123    checkUserAuthModel.auth(titleStr, (authResult: boolean) => {
124      if (authResult) {
125        console.info('checkUserAuth success');
126        if (this.installCertFlag) {
127          if (this.isStartBySheet) {
128            this.startInstallCertBySheet();
129          } else {
130            this.mFaPresenter.startInstallCert(this.context);
131          }
132        } else {
133          if (this.isStartBySheet) {
134            this.startInstallEvidenceBySheet();
135          } else {
136            this.mFaPresenter.startInstallEvidence(this.context);
137          }
138        }
139      }
140    })
141  }
142
143  startInstallCertBySheet(): void {
144    try {
145      let documentSelectOptions = new picker.DocumentSelectOptions();
146      documentSelectOptions.maxSelectNumber = FilterParams.MAX_SELECT_FILE_NUM;
147      documentSelectOptions.fileSuffixFilters = FilterParams.CERT_FILE_SUFFIX;
148      let documentPicker = new picker.DocumentViewPicker(this.context);
149      console.info(TAG + 'start documentPicker.select');
150      documentPicker.select(documentSelectOptions).then((documentSelectResult) => {
151        if (documentSelectResult.length >= 1) {
152          this.routeToNextInstallCert(String(documentSelectResult[0]))
153        } else {
154          console.error(TAG + 'documentPicker.select length invalid:' + documentSelectResult.length);
155        }
156      }).catch((err: BusinessError) => {
157        console.error(TAG + 'documentPicker.select failed with err, message: ' + err.message + ', code: ' + err.code);
158      });
159    } catch (err) {
160      let e: BusinessError = err as BusinessError;
161      console.error(TAG + 'DocumentViewPicker failed with err, message: ' + e.message + ', code: ' + e.code);
162    }
163  }
164
165  routeToNextInstallCert(fileUri: string): void {
166    FileIoModel.getMediaFileSuffix(fileUri, (suffix: string | undefined) => {
167      if (suffix !== undefined) {
168        console.debug(TAG, 'suffix = ', suffix);
169        if ((suffix === 'cer') || (suffix === 'pem') || (suffix === 'crt') || (suffix === 'der') ||
170            (suffix === 'p7b') || (suffix === 'spc')) {
171          CmInstallPresenter.getInstance().installCert(fileUri, '', suffix, false);
172        } else {
173          this.mFaPresenter.unrecognizedFileTips();
174        }
175      }
176    })
177  }
178
179  startInstallEvidenceBySheet(): void {
180    try {
181      let documentSelectOptions = new picker.DocumentSelectOptions();
182      documentSelectOptions.maxSelectNumber = FilterParams.MAX_SELECT_FILE_NUM;
183      documentSelectOptions.fileSuffixFilters = FilterParams.CREDENTIAL_FILE_SUFFIX;
184      let documentPicker = new picker.DocumentViewPicker(this.context);
185      console.info(TAG + 'start documentPicker.select');
186      documentPicker.select(documentSelectOptions).then((documentSelectResult) => {
187        if (documentSelectResult.length >= 1) {
188          this.routeToNextInstallEvidence(String(documentSelectResult[0]))
189        } else {
190          console.error(TAG + 'documentPicker.select length invalid:' + documentSelectResult.length);
191        }
192      }).catch((err: BusinessError) => {
193        console.error(TAG + 'documentPicker.select failed with err, message: ' + err.message + ', code: ' + err.code);
194      });
195    } catch (err) {
196      let e: BusinessError = err as BusinessError;
197      console.error(TAG + 'DocumentViewPicker failed with err, message: ' + e.message + ', code: ' + e.code);
198    }
199  }
200
201  routeToNextInstallEvidence(fileUri: string): void {
202    FileIoModel.getMediaFileSuffix(fileUri, (suffix: string | undefined) => {
203      if (suffix !== undefined) {
204        console.debug(TAG, 'suffix = ', suffix);
205        if ((suffix === 'p12') || (suffix === 'pfx')) {
206          this.selected?.(NavEntryKey.CRED_PWD_INPUT_ENTRY, new CredPwdInputParam(new RouterFileVo(fileUri, suffix)));
207        } else {
208          this.mFaPresenter.unrecognizedFileTips();
209        }
210      }
211    })
212  }
213
214  build() {
215    Column() {
216      GridRow({
217        columns: COPIES_NUM,
218        gutter: vp2px(1) === 2 ? $r('app.float.wh_value_12') : $r('app.float.wh_value_0')
219      }) {
220        GridCol({ span: COPIES_NUM }) {
221          Row({}) {
222            Stack({ alignContent: Alignment.Top }) {
223              Column() {
224                HeadComponent({ headName: $r('app.string.installInStorageDevice'), isStartBySheet: this.isStartBySheet,
225                  icBackIsVisibility: !this.isStartBySheetFirst,
226                  onBackClicked: () => {
227                    this.selected?.(NavEntryKey.POP);
228                  }})
229                  .margin({
230                    top: this.isStartBySheet ? 8 : 0,
231                    left: 12,
232                    right: 12
233                  })
234              }.zIndex(1)
235              .onAreaChange((oldArea, newArea) => {
236                this.headRectHeight = newArea.height as number;
237                this.headRectHeightReal = newArea.height as number;
238              })
239
240              Stack({ alignContent: Alignment.TopEnd }) {
241                Scroll(this.scroller) {
242                  Column() {
243                    Row() {
244                      Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
245                        Text($r('app.string.CA_cert'))
246                          .fontSize($r('sys.float.ohos_id_text_size_body1'))
247                          .fontColor($r('sys.color.ohos_id_color_text_primary'))
248                          .fontWeight(FontWeight.Medium)
249                          .margin({ left: $r('app.float.wh_value_12') })
250                          .textAlign(TextAlign.Start)
251                      }
252                    }
253                    .stateStyles({
254                      normal: this.normalStyle,
255                      pressed: this.pressedStyle
256                    })
257                    .constraintSize({
258                      minHeight: $r('app.float.wh_value_48')
259                    })
260                    .onClick(() => {
261                      this.rootCertificateDialog.open();
262                    })
263
264                    Divider()
265                      .color($r('sys.color.ohos_id_color_list_separator'))
266                      .margin({
267                        left: $r('app.float.wh_value_12'),
268                        right: $r('app.float.wh_value_12')
269                      })
270
271                    Row() {
272                      Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
273                        Text($r('app.string.system_credentials'))
274                          .fontSize($r('sys.float.ohos_id_text_size_body1'))
275                          .fontColor($r('sys.color.ohos_id_color_text_primary'))
276                          .fontWeight(FontWeight.Medium)
277                          .margin({ left: $r('app.float.wh_value_12') })
278                          .textAlign(TextAlign.Start)
279                      }
280                      .onClick(() => {
281                        this.installCertFlag = false;
282                        AppStorage.setOrCreate('installSystemCred', true);
283                        AppStorage.setOrCreate('installUserCred', false);
284                        if (this.isStartBySheet) {
285                          this.startInstallEvidenceBySheet();
286                        } else {
287                          this.mFaPresenter.startInstallEvidence(this.context);
288                        }
289                      })
290                    }
291                    .stateStyles({
292                      normal: this.normalStyle,
293                      pressed: this.pressedStyle
294                    })
295                    .constraintSize({
296                      minHeight: $r('app.float.wh_value_48')
297                    })
298
299                    Divider()
300                      .color($r('sys.color.ohos_id_color_list_separator'))
301                      .margin({
302                        left: $r('app.float.wh_value_12'),
303                        right: $r('app.float.wh_value_12')
304                      })
305
306                    Row() {
307                      Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
308                        Text($r('app.string.user_certificate_credentials'))
309                          .fontSize($r('sys.float.ohos_id_text_size_body1'))
310                          .fontColor($r('sys.color.ohos_id_color_text_primary'))
311                          .fontWeight(FontWeight.Medium)
312                          .margin({ left: $r('app.float.wh_value_12') })
313                          .textAlign(TextAlign.Start)
314                      }
315                      .onClick(() => {
316                        this.installCertFlag = false;
317                        AppStorage.setOrCreate('installUserCred', true);
318                        AppStorage.setOrCreate('installSystemCred', false);
319                        if (this.isStartBySheet) {
320                          this.startInstallEvidenceBySheet();
321                        } else {
322                          this.mFaPresenter.startInstallEvidence(this.context);
323                          new UIContext().getHostContext() as common.Context;
324                        }
325                      })
326                    }
327                    .stateStyles({
328                      normal: this.normalStyle,
329                      pressed: this.pressedStyle
330                    })
331                    .constraintSize({
332                      minHeight: $r('app.float.wh_value_48')
333                    })
334                  }
335                  .padding($r('app.float.wh_value_4'))
336                  .backgroundColor($r('sys.color.ohos_id_color_card_bg'))
337                  .borderRadius($r('app.float.radius_20'))
338                  .width(ComponentConfig.WH_100_100)
339                }
340                .align(Alignment.Top)
341                .scrollable(ScrollDirection.Vertical)
342                .scrollBar(BarState.Off)
343                .width(WidthPercent.WH_100_100)
344                .edgeEffect(EdgeEffect.Spring)
345                .height(this.isStartBySheet ? WidthPercent.WH_AUTO : WidthPercent.WH_100_100)
346                .padding({
347                  left: 16,
348                  right: 16,
349                  bottom: $r('app.float.wh_value_24')
350                }).constraintSize({
351                  minHeight: this.getScrollMinHeight()
352                }).onAreaChange((oldArea, newArea) => {
353                  this.scrollerHeight = newArea.height as number;
354                })
355
356                Column() {
357                  ScrollBar({
358                    scroller: this.scroller,
359                    direction: ScrollBarDirection.Vertical,
360                    state: BarState.Auto
361                  }).margin({
362                    bottom: $r('app.float.wh_value_24')
363                  })
364                }.height(this.scrollerHeight)
365              }.padding({
366                top: this.headRectHeight
367              })
368            }
369            .backgroundColor($r('sys.color.ohos_id_color_sub_background'))
370            .width(WidthPercent.WH_100_100)
371            .height(this.isStartBySheet ? WidthPercent.WH_AUTO : WidthPercent.WH_100_100)
372          }
373          .width(WidthPercent.WH_100_100)
374          .height(this.isStartBySheet ? WidthPercent.WH_AUTO : WidthPercent.WH_100_100);
375        }
376      }
377      .width(WidthPercent.WH_100_100)
378      .height(this.isStartBySheet ? WidthPercent.WH_AUTO : WidthPercent.WH_100_100);
379    }
380    .backgroundColor($r('sys.color.ohos_id_color_sub_background'))
381    .width(WidthPercent.WH_100_100)
382    .height(this.isStartBySheet ? WidthPercent.WH_AUTO : WidthPercent.WH_100_100);
383  }
384
385  getScrollMinHeight() {
386    if (this.sheetParam === undefined || this.headRectHeightReal === 0 ||
387      this.sheetParam.sheetMinHeight < this.headRectHeightReal) {
388      return 0;
389    }
390    return this.sheetParam.sheetMinHeight - this.headRectHeightReal;
391  }
392
393  onPageShow() {
394    let uiExtensionFlag = GlobalContext.getContext().getFlag();
395    let installType: string = GlobalContext.getContext().getAbilityWant().parameters?.installType as string;
396    let uri = GlobalContext.getContext().getAbilityWant().uri ||
397      GlobalContext.getContext().getAbilityWant().parameters?.uri;
398    GlobalContext.getContext().clearAbilityWantUri();
399    GlobalContext.getContext().clearAbilityWantParamsUri();
400    if (uri === 'certInstall') {
401      router.pushUrl({
402        url: 'pages/certInstallFromStorage'
403      })
404    } else if (uri === 'requestAuthorize') {
405      this.mFaPresenter.startRequestAuth(GlobalContext.getContext().getAbilityWant().parameters?.appUid as string);
406    } else if (uiExtensionFlag && uri === 'systemCredInstall' && installType === 'systemCred') {
407      AppStorage.setOrCreate('installSystemCred', true);
408      AppStorage.setOrCreate('installUserCred', false);
409      this.mFaPresenter.startInstallEvidence(this.context);
410    } else if (uiExtensionFlag && uri === 'specifyInstall') {
411      let fileUri = GlobalContext.getContext().getAbilityWant().parameters?.fileUri as string;
412      this.mFaPresenter.startInstall(installType, fileUri);
413    } else {
414      console.error('The want type is not supported');
415    }
416  }
417}