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