Просмотр исходного кода

ionic angular app authentication with keycloak

User 3 лет назад
Родитель
Сommit
7295cd8c78
61 измененных файлов: 1716 добавлений и 25 удалений
  1. 17
    0
      README.md
  2. 9
    0
      angular.json
  3. 111
    0
      config.xml
  4. 4
    1
      ionic.config.json
  5. 9
    0
      ios/.gitignore
  6. 402
    0
      ios/App/App.xcodeproj/project.pbxproj
  7. 7
    0
      ios/App/App.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  8. 10
    0
      ios/App/App.xcworkspace/contents.xcworkspacedata
  9. 8
    0
      ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  10. 60
    0
      ios/App/App/AppDelegate.swift
  11. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@1x.png
  12. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x-1.png
  13. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x.png
  14. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@3x.png
  15. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@1x.png
  16. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x-1.png
  17. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x.png
  18. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@3x.png
  19. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@1x.png
  20. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x-1.png
  21. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x.png
  22. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@3x.png
  23. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png
  24. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@2x.png
  25. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@3x.png
  26. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@1x.png
  27. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@2x.png
  28. Двоичные данные
      ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5x83.5@2x.png
  29. 116
    0
      ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json
  30. 6
    0
      ios/App/App/Assets.xcassets/Contents.json
  31. 23
    0
      ios/App/App/Assets.xcassets/Splash.imageset/Contents.json
  32. Двоичные данные
      ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png
  33. Двоичные данные
      ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png
  34. Двоичные данные
      ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png
  35. 32
    0
      ios/App/App/Base.lproj/LaunchScreen.storyboard
  36. 19
    0
      ios/App/App/Base.lproj/Main.storyboard
  37. 54
    0
      ios/App/App/Info.plist
  38. 6
    0
      ios/App/App/capacitor.config.json
  39. 28
    0
      ios/App/App/config.xml
  40. 22
    0
      ios/App/Podfile
  41. 381
    12
      package-lock.json
  42. 34
    3
      package.json
  43. 7
    1
      src/app/app-routing.module.ts
  44. 26
    4
      src/app/app.module.ts
  45. 36
    0
      src/app/guard/auth.guard.ts
  46. 34
    0
      src/app/init/keycloak-initializer.factory.ts
  47. 17
    0
      src/app/login/login-routing.module.ts
  48. 20
    0
      src/app/login/login.module.ts
  49. 12
    0
      src/app/login/login.page.html
  50. 0
    0
      src/app/login/login.page.scss
  51. 24
    0
      src/app/login/login.page.spec.ts
  52. 27
    0
      src/app/login/login.page.ts
  53. 16
    0
      src/app/services/keycloak/auth-provider.service.spec.ts
  54. 79
    0
      src/app/services/keycloak/auth-provider.service.ts
  55. 1
    1
      src/app/tab3/tab3.page.html
  56. 18
    3
      src/app/tab3/tab3.page.ts
  57. 8
    0
      src/assets/conf/keycloak-local.json
  58. 8
    0
      src/assets/conf/keycloak.json
  59. 7
    0
      src/assets/silent/silent-check-sso.html
  60. 4
    0
      src/shared/constants.ts
  61. 14
    0
      ul_web_hooks/ios/localhost#apple-app-site-association

+ 17
- 0
README.md Просмотреть файл

@@ -0,0 +1,17 @@
1
+#mynatan-ionic-keycloak
2
+
3
+## Installation
4
+
5
+Before proceeding, make sure your computer has Node.js installed. See these instructions to set up an environment for Ionic.
6
+
7
+Install the Ionic CLI with npm:
8
+
9
+npm install -g @ionic/cli
10
+
11
+## Developement Server
12
+
13
+Run ionic serve
14
+
15
+## Deployement on Mobile (Emulator or other...)
16
+
17
+-> https://ionicframework.com/docs/angular/your-first-app/6-deploying-mobile

+ 9
- 0
angular.json Просмотреть файл

@@ -42,6 +42,12 @@
42 42
             "namedChunks": true
43 43
           },
44 44
           "configurations": {
45
+            "local": {
46
+              "optimization": true,
47
+              "sourceMap": true,
48
+              "extractLicenses": true,
49
+              "buildOptimizer": true
50
+            },
45 51
             "production": {
46 52
               "fileReplacements": [
47 53
                 {
@@ -76,6 +82,9 @@
76 82
             "browserTarget": "app:build"
77 83
           },
78 84
           "configurations": {
85
+            "local": {
86
+              "browserTarget": "app:build:local"
87
+            },
79 88
             "production": {
80 89
               "browserTarget": "app:build:production"
81 90
             },

+ 111
- 0
config.xml Просмотреть файл

@@ -0,0 +1,111 @@
1
+<?xml version='1.0' encoding='utf-8'?>
2
+<widget id="io.ionic.starter" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
3
+    <name>mynatan-ionic-keycloak</name>
4
+    <description>An awesome Ionic/Cordova app.</description>
5
+    <author email="hi@ionicframework.com" href="http://ionicframework.com/">Ionic Framework Team</author>
6
+    <content src="index.html" />
7
+    <access origin="*" />
8
+    <allow-intent href="http://*/*" />
9
+    <allow-intent href="https://*/*" />
10
+    <allow-intent href="tel:*" />
11
+    <allow-intent href="sms:*" />
12
+    <allow-intent href="mailto:*" />
13
+    <allow-intent href="geo:*" />
14
+    <preference name="ScrollEnabled" value="false" />
15
+    <preference name="BackupWebStorage" value="none" />
16
+    <preference name="SplashMaintainAspectRatio" value="true" />
17
+    <preference name="FadeSplashScreenDuration" value="300" />
18
+    <preference name="SplashShowOnlyFirstTime" value="false" />
19
+    <preference name="SplashScreen" value="screen" />
20
+    <preference name="SplashScreenDelay" value="3000" />
21
+    <platform name="android">
22
+        <edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application" xmlns:android="http://schemas.android.com/apk/res/android">
23
+            <application android:networkSecurityConfig="@xml/network_security_config" />
24
+        </edit-config>
25
+        <resource-file src="resources/android/xml/network_security_config.xml" target="app/src/main/res/xml/network_security_config.xml" />
26
+        <allow-intent href="market:*" />
27
+        <icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
28
+        <icon density="mdpi" src="resources/android/icon/drawable-mdpi-icon.png" />
29
+        <icon density="hdpi" src="resources/android/icon/drawable-hdpi-icon.png" />
30
+        <icon density="xhdpi" src="resources/android/icon/drawable-xhdpi-icon.png" />
31
+        <icon density="xxhdpi" src="resources/android/icon/drawable-xxhdpi-icon.png" />
32
+        <icon density="xxxhdpi" src="resources/android/icon/drawable-xxxhdpi-icon.png" />
33
+        <splash density="land-ldpi" src="resources/android/splash/drawable-land-ldpi-screen.png" />
34
+        <splash density="land-mdpi" src="resources/android/splash/drawable-land-mdpi-screen.png" />
35
+        <splash density="land-hdpi" src="resources/android/splash/drawable-land-hdpi-screen.png" />
36
+        <splash density="land-xhdpi" src="resources/android/splash/drawable-land-xhdpi-screen.png" />
37
+        <splash density="land-xxhdpi" src="resources/android/splash/drawable-land-xxhdpi-screen.png" />
38
+        <splash density="land-xxxhdpi" src="resources/android/splash/drawable-land-xxxhdpi-screen.png" />
39
+        <splash density="port-ldpi" src="resources/android/splash/drawable-port-ldpi-screen.png" />
40
+        <splash density="port-mdpi" src="resources/android/splash/drawable-port-mdpi-screen.png" />
41
+        <splash density="port-hdpi" src="resources/android/splash/drawable-port-hdpi-screen.png" />
42
+        <splash density="port-xhdpi" src="resources/android/splash/drawable-port-xhdpi-screen.png" />
43
+        <splash density="port-xxhdpi" src="resources/android/splash/drawable-port-xxhdpi-screen.png" />
44
+        <splash density="port-xxxhdpi" src="resources/android/splash/drawable-port-xxxhdpi-screen.png" />
45
+    </platform>
46
+    <platform name="ios">
47
+        <allow-intent href="itms:*" />
48
+        <allow-intent href="itms-apps:*" />
49
+        <icon height="57" src="resources/ios/icon/icon.png" width="57" />
50
+        <icon height="114" src="resources/ios/icon/icon@2x.png" width="114" />
51
+        <icon height="29" src="resources/ios/icon/icon-small.png" width="29" />
52
+        <icon height="58" src="resources/ios/icon/icon-small@2x.png" width="58" />
53
+        <icon height="87" src="resources/ios/icon/icon-small@3x.png" width="87" />
54
+        <icon height="20" src="resources/ios/icon/icon-20.png" width="20" />
55
+        <icon height="40" src="resources/ios/icon/icon-20@2x.png" width="40" />
56
+        <icon height="60" src="resources/ios/icon/icon-20@3x.png" width="60" />
57
+        <icon height="48" src="resources/ios/icon/icon-24@2x.png" width="48" />
58
+        <icon height="55" src="resources/ios/icon/icon-27.5@2x.png" width="55" />
59
+        <icon height="29" src="resources/ios/icon/icon-29.png" width="29" />
60
+        <icon height="58" src="resources/ios/icon/icon-29@2x.png" width="58" />
61
+        <icon height="87" src="resources/ios/icon/icon-29@3x.png" width="87" />
62
+        <icon height="40" src="resources/ios/icon/icon-40.png" width="40" />
63
+        <icon height="80" src="resources/ios/icon/icon-40@2x.png" width="80" />
64
+        <icon height="120" src="resources/ios/icon/icon-40@3x.png" width="120" />
65
+        <icon height="88" src="resources/ios/icon/icon-44@2x.png" width="88" />
66
+        <icon height="50" src="resources/ios/icon/icon-50.png" width="50" />
67
+        <icon height="100" src="resources/ios/icon/icon-50@2x.png" width="100" />
68
+        <icon height="60" src="resources/ios/icon/icon-60.png" width="60" />
69
+        <icon height="120" src="resources/ios/icon/icon-60@2x.png" width="120" />
70
+        <icon height="180" src="resources/ios/icon/icon-60@3x.png" width="180" />
71
+        <icon height="72" src="resources/ios/icon/icon-72.png" width="72" />
72
+        <icon height="144" src="resources/ios/icon/icon-72@2x.png" width="144" />
73
+        <icon height="76" src="resources/ios/icon/icon-76.png" width="76" />
74
+        <icon height="152" src="resources/ios/icon/icon-76@2x.png" width="152" />
75
+        <icon height="167" src="resources/ios/icon/icon-83.5@2x.png" width="167" />
76
+        <icon height="172" src="resources/ios/icon/icon-86@2x.png" width="172" />
77
+        <icon height="196" src="resources/ios/icon/icon-98@2x.png" width="196" />
78
+        <icon height="1024" src="resources/ios/icon/icon-1024.png" width="1024" />
79
+        <splash height="480" src="resources/ios/splash/Default~iphone.png" width="320" />
80
+        <splash height="960" src="resources/ios/splash/Default@2x~iphone.png" width="640" />
81
+        <splash height="1024" src="resources/ios/splash/Default-Portrait~ipad.png" width="768" />
82
+        <splash height="768" src="resources/ios/splash/Default-Landscape~ipad.png" width="1024" />
83
+        <splash height="1125" src="resources/ios/splash/Default-Landscape-2436h.png" width="2436" />
84
+        <splash height="1242" src="resources/ios/splash/Default-Landscape-736h.png" width="2208" />
85
+        <splash height="2048" src="resources/ios/splash/Default-Portrait@2x~ipad.png" width="1536" />
86
+        <splash height="1536" src="resources/ios/splash/Default-Landscape@2x~ipad.png" width="2048" />
87
+        <splash height="2732" src="resources/ios/splash/Default-Portrait@~ipadpro.png" width="2048" />
88
+        <splash height="2048" src="resources/ios/splash/Default-Landscape@~ipadpro.png" width="2732" />
89
+        <splash height="1136" src="resources/ios/splash/Default-568h@2x~iphone.png" width="640" />
90
+        <splash height="1334" src="resources/ios/splash/Default-667h.png" width="750" />
91
+        <splash height="2208" src="resources/ios/splash/Default-736h.png" width="1242" />
92
+        <splash height="2436" src="resources/ios/splash/Default-2436h.png" width="1125" />
93
+        <splash height="2732" src="resources/ios/splash/Default@2x~universal~anyany.png" width="2732" />
94
+        <icon height="216" src="resources/ios/icon/icon-108@2x.png" width="216" />
95
+        <splash height="2688" src="resources/ios/splash/Default-2688h~iphone.png" width="1242" />
96
+        <splash height="1242" src="resources/ios/splash/Default-Landscape-2688h~iphone.png" width="2688" />
97
+        <splash height="1792" src="resources/ios/splash/Default-1792h~iphone.png" width="828" />
98
+        <splash height="828" src="resources/ios/splash/Default-Landscape-1792h~iphone.png" width="1792" />
99
+    </platform>
100
+    <plugin name="cordova-plugin-whitelist" spec="1.3.3" />
101
+    <plugin name="cordova-plugin-statusbar" spec="2.4.2" />
102
+    <plugin name="cordova-plugin-device" spec="2.0.2" />
103
+    <plugin name="cordova-plugin-splashscreen" spec="5.0.2" />
104
+    <plugin name="cordova-plugin-ionic-webview" spec="^4.0.0" />
105
+    <plugin name="cordova-plugin-ionic-keyboard" spec="^2.0.5" />
106
+    <universal-links>
107
+        <host name="localhost">
108
+            <path url="*" />
109
+        </host>
110
+    </universal-links>
111
+</widget>

+ 4
- 1
ionic.config.json Просмотреть файл

@@ -1,7 +1,10 @@
1 1
 {
2 2
   "name": "mynatan-ionic-keycloak",
3 3
   "integrations": {
4
-    "capacitor": {}
4
+    "capacitor": {},
5
+    "cordova": {
6
+      "enabled": false
7
+    }
5 8
   },
6 9
   "type": "angular"
7 10
 }

+ 9
- 0
ios/.gitignore Просмотреть файл

@@ -0,0 +1,9 @@
1
+App/build
2
+App/Pods
3
+App/Podfile.lock
4
+App/App/public
5
+DerivedData
6
+xcuserdata
7
+
8
+# Cordova plugins for Capacitor
9
+capacitor-cordova-ios-plugins

+ 402
- 0
ios/App/App.xcodeproj/project.pbxproj Просмотреть файл

@@ -0,0 +1,402 @@
1
+// !$*UTF8*$!
2
+{
3
+	archiveVersion = 1;
4
+	classes = {
5
+	};
6
+	objectVersion = 48;
7
+	objects = {
8
+
9
+/* Begin PBXBuildFile section */
10
+		2FAD9763203C412B000D30F8 /* config.xml in Resources */ = {isa = PBXBuildFile; fileRef = 2FAD9762203C412B000D30F8 /* config.xml */; };
11
+		50379B232058CBB4000EE86E /* capacitor.config.json in Resources */ = {isa = PBXBuildFile; fileRef = 50379B222058CBB4000EE86E /* capacitor.config.json */; };
12
+		504EC3081FED79650016851F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504EC3071FED79650016851F /* AppDelegate.swift */; };
13
+		504EC30D1FED79650016851F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30B1FED79650016851F /* Main.storyboard */; };
14
+		504EC30F1FED79650016851F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30E1FED79650016851F /* Assets.xcassets */; };
15
+		504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC3101FED79650016851F /* LaunchScreen.storyboard */; };
16
+		50B271D11FEDC1A000F3C39B /* public in Resources */ = {isa = PBXBuildFile; fileRef = 50B271D01FEDC1A000F3C39B /* public */; };
17
+		A084ECDBA7D38E1E42DFC39D /* Pods_App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */; };
18
+/* End PBXBuildFile section */
19
+
20
+/* Begin PBXFileReference section */
21
+		2FAD9762203C412B000D30F8 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = config.xml; sourceTree = "<group>"; };
22
+		50379B222058CBB4000EE86E /* capacitor.config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = capacitor.config.json; sourceTree = "<group>"; };
23
+		504EC3041FED79650016851F /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; };
24
+		504EC3071FED79650016851F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
25
+		504EC30C1FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
26
+		504EC30E1FED79650016851F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
27
+		504EC3111FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
28
+		504EC3131FED79650016851F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
29
+		50B271D01FEDC1A000F3C39B /* public */ = {isa = PBXFileReference; lastKnownFileType = folder; path = public; sourceTree = "<group>"; };
30
+		AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_App.framework; sourceTree = BUILT_PRODUCTS_DIR; };
31
+		AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.release.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.release.xcconfig"; sourceTree = "<group>"; };
32
+		FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = "<group>"; };
33
+/* End PBXFileReference section */
34
+
35
+/* Begin PBXFrameworksBuildPhase section */
36
+		504EC3011FED79650016851F /* Frameworks */ = {
37
+			isa = PBXFrameworksBuildPhase;
38
+			buildActionMask = 2147483647;
39
+			files = (
40
+				A084ECDBA7D38E1E42DFC39D /* Pods_App.framework in Frameworks */,
41
+			);
42
+			runOnlyForDeploymentPostprocessing = 0;
43
+		};
44
+/* End PBXFrameworksBuildPhase section */
45
+
46
+/* Begin PBXGroup section */
47
+		27E2DDA53C4D2A4D1A88CE4A /* Frameworks */ = {
48
+			isa = PBXGroup;
49
+			children = (
50
+				AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */,
51
+			);
52
+			name = Frameworks;
53
+			sourceTree = "<group>";
54
+		};
55
+		504EC2FB1FED79650016851F = {
56
+			isa = PBXGroup;
57
+			children = (
58
+				504EC3061FED79650016851F /* App */,
59
+				504EC3051FED79650016851F /* Products */,
60
+				7F8756D8B27F46E3366F6CEA /* Pods */,
61
+				27E2DDA53C4D2A4D1A88CE4A /* Frameworks */,
62
+			);
63
+			sourceTree = "<group>";
64
+		};
65
+		504EC3051FED79650016851F /* Products */ = {
66
+			isa = PBXGroup;
67
+			children = (
68
+				504EC3041FED79650016851F /* App.app */,
69
+			);
70
+			name = Products;
71
+			sourceTree = "<group>";
72
+		};
73
+		504EC3061FED79650016851F /* App */ = {
74
+			isa = PBXGroup;
75
+			children = (
76
+				50379B222058CBB4000EE86E /* capacitor.config.json */,
77
+				504EC3071FED79650016851F /* AppDelegate.swift */,
78
+				504EC30B1FED79650016851F /* Main.storyboard */,
79
+				504EC30E1FED79650016851F /* Assets.xcassets */,
80
+				504EC3101FED79650016851F /* LaunchScreen.storyboard */,
81
+				504EC3131FED79650016851F /* Info.plist */,
82
+				2FAD9762203C412B000D30F8 /* config.xml */,
83
+				50B271D01FEDC1A000F3C39B /* public */,
84
+			);
85
+			path = App;
86
+			sourceTree = "<group>";
87
+		};
88
+		7F8756D8B27F46E3366F6CEA /* Pods */ = {
89
+			isa = PBXGroup;
90
+			children = (
91
+				FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */,
92
+				AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */,
93
+			);
94
+			name = Pods;
95
+			sourceTree = "<group>";
96
+		};
97
+/* End PBXGroup section */
98
+
99
+/* Begin PBXNativeTarget section */
100
+		504EC3031FED79650016851F /* App */ = {
101
+			isa = PBXNativeTarget;
102
+			buildConfigurationList = 504EC3161FED79650016851F /* Build configuration list for PBXNativeTarget "App" */;
103
+			buildPhases = (
104
+				6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */,
105
+				504EC3001FED79650016851F /* Sources */,
106
+				504EC3011FED79650016851F /* Frameworks */,
107
+				504EC3021FED79650016851F /* Resources */,
108
+				9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */,
109
+			);
110
+			buildRules = (
111
+			);
112
+			dependencies = (
113
+			);
114
+			name = App;
115
+			productName = App;
116
+			productReference = 504EC3041FED79650016851F /* App.app */;
117
+			productType = "com.apple.product-type.application";
118
+		};
119
+/* End PBXNativeTarget section */
120
+
121
+/* Begin PBXProject section */
122
+		504EC2FC1FED79650016851F /* Project object */ = {
123
+			isa = PBXProject;
124
+			attributes = {
125
+				LastSwiftUpdateCheck = 0920;
126
+				LastUpgradeCheck = 0920;
127
+				TargetAttributes = {
128
+					504EC3031FED79650016851F = {
129
+						CreatedOnToolsVersion = 9.2;
130
+						LastSwiftMigration = 1100;
131
+						ProvisioningStyle = Automatic;
132
+					};
133
+				};
134
+			};
135
+			buildConfigurationList = 504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */;
136
+			compatibilityVersion = "Xcode 8.0";
137
+			developmentRegion = en;
138
+			hasScannedForEncodings = 0;
139
+			knownRegions = (
140
+				en,
141
+				Base,
142
+			);
143
+			mainGroup = 504EC2FB1FED79650016851F;
144
+			productRefGroup = 504EC3051FED79650016851F /* Products */;
145
+			projectDirPath = "";
146
+			projectRoot = "";
147
+			targets = (
148
+				504EC3031FED79650016851F /* App */,
149
+			);
150
+		};
151
+/* End PBXProject section */
152
+
153
+/* Begin PBXResourcesBuildPhase section */
154
+		504EC3021FED79650016851F /* Resources */ = {
155
+			isa = PBXResourcesBuildPhase;
156
+			buildActionMask = 2147483647;
157
+			files = (
158
+				504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */,
159
+				50B271D11FEDC1A000F3C39B /* public in Resources */,
160
+				504EC30F1FED79650016851F /* Assets.xcassets in Resources */,
161
+				50379B232058CBB4000EE86E /* capacitor.config.json in Resources */,
162
+				504EC30D1FED79650016851F /* Main.storyboard in Resources */,
163
+				2FAD9763203C412B000D30F8 /* config.xml in Resources */,
164
+			);
165
+			runOnlyForDeploymentPostprocessing = 0;
166
+		};
167
+/* End PBXResourcesBuildPhase section */
168
+
169
+/* Begin PBXShellScriptBuildPhase section */
170
+		6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */ = {
171
+			isa = PBXShellScriptBuildPhase;
172
+			buildActionMask = 2147483647;
173
+			files = (
174
+			);
175
+			inputPaths = (
176
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
177
+				"${PODS_ROOT}/Manifest.lock",
178
+			);
179
+			name = "[CP] Check Pods Manifest.lock";
180
+			outputPaths = (
181
+				"$(DERIVED_FILE_DIR)/Pods-App-checkManifestLockResult.txt",
182
+			);
183
+			runOnlyForDeploymentPostprocessing = 0;
184
+			shellPath = /bin/sh;
185
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
186
+			showEnvVarsInLog = 0;
187
+		};
188
+		9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */ = {
189
+			isa = PBXShellScriptBuildPhase;
190
+			buildActionMask = 2147483647;
191
+			files = (
192
+			);
193
+			inputPaths = (
194
+			);
195
+			name = "[CP] Embed Pods Frameworks";
196
+			outputPaths = (
197
+			);
198
+			runOnlyForDeploymentPostprocessing = 0;
199
+			shellPath = /bin/sh;
200
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-App/Pods-App-frameworks.sh\"\n";
201
+			showEnvVarsInLog = 0;
202
+		};
203
+/* End PBXShellScriptBuildPhase section */
204
+
205
+/* Begin PBXSourcesBuildPhase section */
206
+		504EC3001FED79650016851F /* Sources */ = {
207
+			isa = PBXSourcesBuildPhase;
208
+			buildActionMask = 2147483647;
209
+			files = (
210
+				504EC3081FED79650016851F /* AppDelegate.swift in Sources */,
211
+			);
212
+			runOnlyForDeploymentPostprocessing = 0;
213
+		};
214
+/* End PBXSourcesBuildPhase section */
215
+
216
+/* Begin PBXVariantGroup section */
217
+		504EC30B1FED79650016851F /* Main.storyboard */ = {
218
+			isa = PBXVariantGroup;
219
+			children = (
220
+				504EC30C1FED79650016851F /* Base */,
221
+			);
222
+			name = Main.storyboard;
223
+			sourceTree = "<group>";
224
+		};
225
+		504EC3101FED79650016851F /* LaunchScreen.storyboard */ = {
226
+			isa = PBXVariantGroup;
227
+			children = (
228
+				504EC3111FED79650016851F /* Base */,
229
+			);
230
+			name = LaunchScreen.storyboard;
231
+			sourceTree = "<group>";
232
+		};
233
+/* End PBXVariantGroup section */
234
+
235
+/* Begin XCBuildConfiguration section */
236
+		504EC3141FED79650016851F /* Debug */ = {
237
+			isa = XCBuildConfiguration;
238
+			buildSettings = {
239
+				ALWAYS_SEARCH_USER_PATHS = NO;
240
+				CLANG_ANALYZER_NONNULL = YES;
241
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
242
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
243
+				CLANG_CXX_LIBRARY = "libc++";
244
+				CLANG_ENABLE_MODULES = YES;
245
+				CLANG_ENABLE_OBJC_ARC = YES;
246
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
247
+				CLANG_WARN_BOOL_CONVERSION = YES;
248
+				CLANG_WARN_COMMA = YES;
249
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
250
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
251
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
252
+				CLANG_WARN_EMPTY_BODY = YES;
253
+				CLANG_WARN_ENUM_CONVERSION = YES;
254
+				CLANG_WARN_INFINITE_RECURSION = YES;
255
+				CLANG_WARN_INT_CONVERSION = YES;
256
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
257
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
258
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
259
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
260
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
261
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
262
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
263
+				CLANG_WARN_UNREACHABLE_CODE = YES;
264
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
265
+				CODE_SIGN_IDENTITY = "iPhone Developer";
266
+				COPY_PHASE_STRIP = NO;
267
+				DEBUG_INFORMATION_FORMAT = dwarf;
268
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
269
+				ENABLE_TESTABILITY = YES;
270
+				GCC_C_LANGUAGE_STANDARD = gnu11;
271
+				GCC_DYNAMIC_NO_PIC = NO;
272
+				GCC_NO_COMMON_BLOCKS = YES;
273
+				GCC_OPTIMIZATION_LEVEL = 0;
274
+				GCC_PREPROCESSOR_DEFINITIONS = (
275
+					"DEBUG=1",
276
+					"$(inherited)",
277
+				);
278
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
279
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
280
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
281
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
282
+				GCC_WARN_UNUSED_FUNCTION = YES;
283
+				GCC_WARN_UNUSED_VARIABLE = YES;
284
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
285
+				MTL_ENABLE_DEBUG_INFO = YES;
286
+				ONLY_ACTIVE_ARCH = YES;
287
+				SDKROOT = iphoneos;
288
+				SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
289
+				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
290
+			};
291
+			name = Debug;
292
+		};
293
+		504EC3151FED79650016851F /* Release */ = {
294
+			isa = XCBuildConfiguration;
295
+			buildSettings = {
296
+				ALWAYS_SEARCH_USER_PATHS = NO;
297
+				CLANG_ANALYZER_NONNULL = YES;
298
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
299
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
300
+				CLANG_CXX_LIBRARY = "libc++";
301
+				CLANG_ENABLE_MODULES = YES;
302
+				CLANG_ENABLE_OBJC_ARC = YES;
303
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
304
+				CLANG_WARN_BOOL_CONVERSION = YES;
305
+				CLANG_WARN_COMMA = YES;
306
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
307
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
308
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
309
+				CLANG_WARN_EMPTY_BODY = YES;
310
+				CLANG_WARN_ENUM_CONVERSION = YES;
311
+				CLANG_WARN_INFINITE_RECURSION = YES;
312
+				CLANG_WARN_INT_CONVERSION = YES;
313
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
314
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
315
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
316
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
317
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
318
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
319
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
320
+				CLANG_WARN_UNREACHABLE_CODE = YES;
321
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
322
+				CODE_SIGN_IDENTITY = "iPhone Developer";
323
+				COPY_PHASE_STRIP = NO;
324
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
325
+				ENABLE_NS_ASSERTIONS = NO;
326
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
327
+				GCC_C_LANGUAGE_STANDARD = gnu11;
328
+				GCC_NO_COMMON_BLOCKS = YES;
329
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
330
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
331
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
332
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
333
+				GCC_WARN_UNUSED_FUNCTION = YES;
334
+				GCC_WARN_UNUSED_VARIABLE = YES;
335
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
336
+				MTL_ENABLE_DEBUG_INFO = NO;
337
+				SDKROOT = iphoneos;
338
+				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
339
+				VALIDATE_PRODUCT = YES;
340
+			};
341
+			name = Release;
342
+		};
343
+		504EC3171FED79650016851F /* Debug */ = {
344
+			isa = XCBuildConfiguration;
345
+			baseConfigurationReference = FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */;
346
+			buildSettings = {
347
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
348
+				CODE_SIGN_STYLE = Automatic;
349
+				INFOPLIST_FILE = App/Info.plist;
350
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
351
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
352
+				OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
353
+				PRODUCT_BUNDLE_IDENTIFIER = io.ionic.starter;
354
+				PRODUCT_NAME = "$(TARGET_NAME)";
355
+				SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
356
+				SWIFT_VERSION = 5.0;
357
+				TARGETED_DEVICE_FAMILY = "1,2";
358
+			};
359
+			name = Debug;
360
+		};
361
+		504EC3181FED79650016851F /* Release */ = {
362
+			isa = XCBuildConfiguration;
363
+			baseConfigurationReference = AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */;
364
+			buildSettings = {
365
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
366
+				CODE_SIGN_STYLE = Automatic;
367
+				INFOPLIST_FILE = App/Info.plist;
368
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
369
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
370
+				PRODUCT_BUNDLE_IDENTIFIER = io.ionic.starter;
371
+				PRODUCT_NAME = "$(TARGET_NAME)";
372
+				SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
373
+				SWIFT_VERSION = 5.0;
374
+				TARGETED_DEVICE_FAMILY = "1,2";
375
+			};
376
+			name = Release;
377
+		};
378
+/* End XCBuildConfiguration section */
379
+
380
+/* Begin XCConfigurationList section */
381
+		504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */ = {
382
+			isa = XCConfigurationList;
383
+			buildConfigurations = (
384
+				504EC3141FED79650016851F /* Debug */,
385
+				504EC3151FED79650016851F /* Release */,
386
+			);
387
+			defaultConfigurationIsVisible = 0;
388
+			defaultConfigurationName = Release;
389
+		};
390
+		504EC3161FED79650016851F /* Build configuration list for PBXNativeTarget "App" */ = {
391
+			isa = XCConfigurationList;
392
+			buildConfigurations = (
393
+				504EC3171FED79650016851F /* Debug */,
394
+				504EC3181FED79650016851F /* Release */,
395
+			);
396
+			defaultConfigurationIsVisible = 0;
397
+			defaultConfigurationName = Release;
398
+		};
399
+/* End XCConfigurationList section */
400
+	};
401
+	rootObject = 504EC2FC1FED79650016851F /* Project object */;
402
+}

+ 7
- 0
ios/App/App.xcodeproj/project.xcworkspace/contents.xcworkspacedata Просмотреть файл

@@ -0,0 +1,7 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<Workspace
3
+   version = "1.0">
4
+   <FileRef
5
+      location = "self:App.xcodeproj">
6
+   </FileRef>
7
+</Workspace>

+ 10
- 0
ios/App/App.xcworkspace/contents.xcworkspacedata Просмотреть файл

@@ -0,0 +1,10 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<Workspace
3
+   version = "1.0">
4
+   <FileRef
5
+      location = "group:App.xcodeproj">
6
+   </FileRef>
7
+   <FileRef
8
+      location = "group:Pods/Pods.xcodeproj">
9
+   </FileRef>
10
+</Workspace>

+ 8
- 0
ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist Просмотреть файл

@@ -0,0 +1,8 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+	<key>IDEDidComputeMac32BitWarning</key>
6
+	<true/>
7
+</dict>
8
+</plist>

+ 60
- 0
ios/App/App/AppDelegate.swift Просмотреть файл

@@ -0,0 +1,60 @@
1
+import UIKit
2
+import Capacitor
3
+
4
+@UIApplicationMain
5
+class AppDelegate: UIResponder, UIApplicationDelegate {
6
+
7
+    var window: UIWindow?
8
+
9
+    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
10
+        // Override point for customization after application launch.
11
+        return true
12
+    }
13
+
14
+    func applicationWillResignActive(_ application: UIApplication) {
15
+        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
16
+        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
17
+    }
18
+
19
+    func applicationDidEnterBackground(_ application: UIApplication) {
20
+        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
21
+        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
22
+    }
23
+
24
+    func applicationWillEnterForeground(_ application: UIApplication) {
25
+        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
26
+    }
27
+
28
+    func applicationDidBecomeActive(_ application: UIApplication) {
29
+        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
30
+    }
31
+
32
+    func applicationWillTerminate(_ application: UIApplication) {
33
+        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
34
+    }
35
+
36
+    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
37
+        // Called when the app was launched with a url. Feel free to add additional processing here,
38
+        // but if you want the App API to support tracking app url opens, make sure to keep this call
39
+        return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
40
+    }
41
+
42
+    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
43
+        // Called when the app was launched with an activity, including Universal Links.
44
+        // Feel free to add additional processing here, but if you want the App API to support
45
+        // tracking app url opens, make sure to keep this call
46
+        return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
47
+    }
48
+
49
+    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
50
+        super.touchesBegan(touches, with: event)
51
+
52
+        let statusBarRect = UIApplication.shared.statusBarFrame
53
+        guard let touchPoint = event?.allTouches?.first?.location(in: self.window) else { return }
54
+
55
+        if statusBarRect.contains(touchPoint) {
56
+            NotificationCenter.default.post(name: .capacitorStatusBarTapped, object: nil)
57
+        }
58
+    }
59
+
60
+}

Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@1x.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x-1.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@3x.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@1x.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x-1.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@3x.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@1x.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x-1.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@3x.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@2x.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@3x.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@1x.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@2x.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5x83.5@2x.png Просмотреть файл


+ 116
- 0
ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json Просмотреть файл

@@ -0,0 +1,116 @@
1
+{
2
+  "images" : [
3
+    {
4
+      "size" : "20x20",
5
+      "idiom" : "iphone",
6
+      "filename" : "AppIcon-20x20@2x.png",
7
+      "scale" : "2x"
8
+    },
9
+    {
10
+      "size" : "20x20",
11
+      "idiom" : "iphone",
12
+      "filename" : "AppIcon-20x20@3x.png",
13
+      "scale" : "3x"
14
+    },
15
+    {
16
+      "size" : "29x29",
17
+      "idiom" : "iphone",
18
+      "filename" : "AppIcon-29x29@2x-1.png",
19
+      "scale" : "2x"
20
+    },
21
+    {
22
+      "size" : "29x29",
23
+      "idiom" : "iphone",
24
+      "filename" : "AppIcon-29x29@3x.png",
25
+      "scale" : "3x"
26
+    },
27
+    {
28
+      "size" : "40x40",
29
+      "idiom" : "iphone",
30
+      "filename" : "AppIcon-40x40@2x.png",
31
+      "scale" : "2x"
32
+    },
33
+    {
34
+      "size" : "40x40",
35
+      "idiom" : "iphone",
36
+      "filename" : "AppIcon-40x40@3x.png",
37
+      "scale" : "3x"
38
+    },
39
+    {
40
+      "size" : "60x60",
41
+      "idiom" : "iphone",
42
+      "filename" : "AppIcon-60x60@2x.png",
43
+      "scale" : "2x"
44
+    },
45
+    {
46
+      "size" : "60x60",
47
+      "idiom" : "iphone",
48
+      "filename" : "AppIcon-60x60@3x.png",
49
+      "scale" : "3x"
50
+    },
51
+    {
52
+      "size" : "20x20",
53
+      "idiom" : "ipad",
54
+      "filename" : "AppIcon-20x20@1x.png",
55
+      "scale" : "1x"
56
+    },
57
+    {
58
+      "size" : "20x20",
59
+      "idiom" : "ipad",
60
+      "filename" : "AppIcon-20x20@2x-1.png",
61
+      "scale" : "2x"
62
+    },
63
+    {
64
+      "size" : "29x29",
65
+      "idiom" : "ipad",
66
+      "filename" : "AppIcon-29x29@1x.png",
67
+      "scale" : "1x"
68
+    },
69
+    {
70
+      "size" : "29x29",
71
+      "idiom" : "ipad",
72
+      "filename" : "AppIcon-29x29@2x.png",
73
+      "scale" : "2x"
74
+    },
75
+    {
76
+      "size" : "40x40",
77
+      "idiom" : "ipad",
78
+      "filename" : "AppIcon-40x40@1x.png",
79
+      "scale" : "1x"
80
+    },
81
+    {
82
+      "size" : "40x40",
83
+      "idiom" : "ipad",
84
+      "filename" : "AppIcon-40x40@2x-1.png",
85
+      "scale" : "2x"
86
+    },
87
+    {
88
+      "size" : "76x76",
89
+      "idiom" : "ipad",
90
+      "filename" : "AppIcon-76x76@1x.png",
91
+      "scale" : "1x"
92
+    },
93
+    {
94
+      "size" : "76x76",
95
+      "idiom" : "ipad",
96
+      "filename" : "AppIcon-76x76@2x.png",
97
+      "scale" : "2x"
98
+    },
99
+    {
100
+      "size" : "83.5x83.5",
101
+      "idiom" : "ipad",
102
+      "filename" : "AppIcon-83.5x83.5@2x.png",
103
+      "scale" : "2x"
104
+    },
105
+    {
106
+      "size" : "1024x1024",
107
+      "idiom" : "ios-marketing",
108
+      "filename" : "AppIcon-512@2x.png",
109
+      "scale" : "1x"
110
+    }
111
+  ],
112
+  "info" : {
113
+    "version" : 1,
114
+    "author" : "xcode"
115
+  }
116
+}

+ 6
- 0
ios/App/App/Assets.xcassets/Contents.json Просмотреть файл

@@ -0,0 +1,6 @@
1
+{
2
+  "info" : {
3
+    "version" : 1,
4
+    "author" : "xcode"
5
+  }
6
+}

+ 23
- 0
ios/App/App/Assets.xcassets/Splash.imageset/Contents.json Просмотреть файл

@@ -0,0 +1,23 @@
1
+{
2
+  "images" : [
3
+    {
4
+      "idiom" : "universal",
5
+      "filename" : "splash-2732x2732-2.png",
6
+      "scale" : "1x"
7
+    },
8
+    {
9
+      "idiom" : "universal",
10
+      "filename" : "splash-2732x2732-1.png",
11
+      "scale" : "2x"
12
+    },
13
+    {
14
+      "idiom" : "universal",
15
+      "filename" : "splash-2732x2732.png",
16
+      "scale" : "3x"
17
+    }
18
+  ],
19
+  "info" : {
20
+    "version" : 1,
21
+    "author" : "xcode"
22
+  }
23
+}

Двоичные данные
ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png Просмотреть файл


Двоичные данные
ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png Просмотреть файл


+ 32
- 0
ios/App/App/Base.lproj/LaunchScreen.storyboard Просмотреть файл

@@ -0,0 +1,32 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17132" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
3
+    <device id="retina4_7" orientation="portrait" appearance="light"/>
4
+    <dependencies>
5
+        <deployment identifier="iOS"/>
6
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17105"/>
7
+        <capability name="System colors in document resources" minToolsVersion="11.0"/>
8
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
9
+    </dependencies>
10
+    <scenes>
11
+        <!--View Controller-->
12
+        <scene sceneID="EHf-IW-A2E">
13
+            <objects>
14
+                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
15
+                    <imageView key="view" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Splash" id="snD-IY-ifK">
16
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
17
+                        <autoresizingMask key="autoresizingMask"/>
18
+                        <color key="backgroundColor" systemColor="systemBackgroundColor"/>
19
+                    </imageView>
20
+                </viewController>
21
+                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
22
+            </objects>
23
+            <point key="canvasLocation" x="53" y="375"/>
24
+        </scene>
25
+    </scenes>
26
+    <resources>
27
+        <image name="Splash" width="1366" height="1366"/>
28
+        <systemColor name="systemBackgroundColor">
29
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
30
+        </systemColor>
31
+    </resources>
32
+</document>

+ 19
- 0
ios/App/App/Base.lproj/Main.storyboard Просмотреть файл

@@ -0,0 +1,19 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14111" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
3
+    <device id="retina4_7" orientation="portrait">
4
+        <adaptation id="fullscreen"/>
5
+    </device>
6
+    <dependencies>
7
+        <deployment identifier="iOS"/>
8
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
9
+    </dependencies>
10
+    <scenes>
11
+        <!--Bridge View Controller-->
12
+        <scene sceneID="tne-QT-ifu">
13
+            <objects>
14
+                <viewController id="BYZ-38-t0r" customClass="CAPBridgeViewController" customModule="Capacitor" sceneMemberID="viewController"/>
15
+                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
16
+            </objects>
17
+        </scene>
18
+    </scenes>
19
+</document>

+ 54
- 0
ios/App/App/Info.plist Просмотреть файл

@@ -0,0 +1,54 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+	<key>CFBundleDevelopmentRegion</key>
6
+	<string>en</string>
7
+	<key>CFBundleDisplayName</key>
8
+        <string>mynatan-ionic-keycloak</string>
9
+	<key>CFBundleExecutable</key>
10
+	<string>$(EXECUTABLE_NAME)</string>
11
+	<key>CFBundleIdentifier</key>
12
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
13
+	<key>CFBundleInfoDictionaryVersion</key>
14
+	<string>6.0</string>
15
+	<key>CFBundleName</key>
16
+	<string>$(PRODUCT_NAME)</string>
17
+	<key>CFBundlePackageType</key>
18
+	<string>APPL</string>
19
+	<key>CFBundleShortVersionString</key>
20
+	<string>1.0</string>
21
+	<key>CFBundleVersion</key>
22
+	<string>1</string>
23
+	<key>LSRequiresIPhoneOS</key>
24
+	<true/>
25
+	<key>NSAppTransportSecurity</key>
26
+	<dict>
27
+		<key>NSAllowsArbitraryLoads</key>
28
+		<true/>
29
+	</dict>
30
+	<key>UILaunchStoryboardName</key>
31
+	<string>LaunchScreen</string>
32
+	<key>UIMainStoryboardFile</key>
33
+	<string>Main</string>
34
+	<key>UIRequiredDeviceCapabilities</key>
35
+	<array>
36
+		<string>armv7</string>
37
+	</array>
38
+	<key>UISupportedInterfaceOrientations</key>
39
+	<array>
40
+		<string>UIInterfaceOrientationPortrait</string>
41
+		<string>UIInterfaceOrientationLandscapeLeft</string>
42
+		<string>UIInterfaceOrientationLandscapeRight</string>
43
+	</array>
44
+	<key>UISupportedInterfaceOrientations~ipad</key>
45
+	<array>
46
+		<string>UIInterfaceOrientationPortrait</string>
47
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
48
+		<string>UIInterfaceOrientationLandscapeLeft</string>
49
+		<string>UIInterfaceOrientationLandscapeRight</string>
50
+	</array>
51
+	<key>UIViewControllerBasedStatusBarAppearance</key>
52
+	<true/>
53
+</dict>
54
+</plist>

+ 6
- 0
ios/App/App/capacitor.config.json Просмотреть файл

@@ -0,0 +1,6 @@
1
+{
2
+	"appId": "io.ionic.starter",
3
+	"appName": "mynatan-ionic-keycloak",
4
+	"webDir": "www",
5
+	"bundledWebRuntime": false
6
+}

+ 28
- 0
ios/App/App/config.xml Просмотреть файл

@@ -0,0 +1,28 @@
1
+<?xml version='1.0' encoding='utf-8'?>
2
+<widget version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
3
+  <access origin="*" />
4
+  
5
+  <feature name="InAppBrowser">
6
+    <param name="ios-package" value="CDVWKInAppBrowser"/>
7
+    <param name="onload" value="true"/>
8
+  </feature>
9
+
10
+  <feature name="IonicDeeplinkPlugin">
11
+    <param name="ios-package" value="IonicDeeplinkPlugin" onload="true"/>
12
+  </feature>
13
+
14
+  <feature name="BrowserTab">
15
+    <param name="ios-package" value="CBTBrowserTab"/>
16
+  </feature>
17
+
18
+  <feature name="UniversalLinks">
19
+    <param name="ios-package" value="CULPlugin"/>
20
+    <param name="onload" value="true"/>
21
+  </feature>
22
+
23
+  <feature name="Device">
24
+    <param name="ios-package" value="CDVDevice"/>
25
+  </feature>
26
+
27
+  
28
+</widget>

+ 22
- 0
ios/App/Podfile Просмотреть файл

@@ -0,0 +1,22 @@
1
+platform :ios, '12.0'
2
+use_frameworks!
3
+
4
+# workaround to avoid Xcode caching of Pods that requires
5
+# Product -> Clean Build Folder after new Cordova plugins installed
6
+# Requires CocoaPods 1.6 or newer
7
+install! 'cocoapods', :disable_input_output_paths => true
8
+
9
+def capacitor_pods
10
+  pod 'Capacitor', :path => '../../node_modules/@capacitor/ios'
11
+  pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
12
+  pod 'CapacitorApp', :path => '../../node_modules/@capacitor/app'
13
+  pod 'CapacitorHaptics', :path => '../../node_modules/@capacitor/haptics'
14
+  pod 'CapacitorKeyboard', :path => '../../node_modules/@capacitor/keyboard'
15
+  pod 'CapacitorStatusBar', :path => '../../node_modules/@capacitor/status-bar'
16
+  pod 'CordovaPlugins', :path => '../capacitor-cordova-ios-plugins'
17
+end
18
+
19
+target 'App' do
20
+  capacitor_pods
21
+  # Add your Pods here
22
+end

+ 381
- 12
package-lock.json Просмотреть файл

@@ -1595,6 +1595,11 @@
1595 1595
       "resolved": "https://registry.npmjs.org/@capacitor/haptics/-/haptics-1.0.2.tgz",
1596 1596
       "integrity": "sha512-ex629YmC439cqJcBX0HRTLtQ5lRc+Grx2/EPDLPEK33aTMcwplOsY8IQdjKL2pmO44AX4BmYtztui14Mf89q/g=="
1597 1597
     },
1598
+    "@capacitor/ios": {
1599
+      "version": "3.1.2",
1600
+      "resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-3.1.2.tgz",
1601
+      "integrity": "sha512-y6wnTLK0I/ckTuofzeRkXK0OPw6vAKOj0I6QXwg2DxDdtiHmed6qP/G8cvwNBiFhZE9xfXAulxRYP8D76TPtNQ=="
1602
+    },
1598 1603
     "@capacitor/keyboard": {
1599 1604
       "version": "1.0.2",
1600 1605
       "resolved": "https://registry.npmjs.org/@capacitor/keyboard/-/keyboard-1.0.2.tgz",
@@ -1692,6 +1697,14 @@
1692 1697
       "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==",
1693 1698
       "dev": true
1694 1699
     },
1700
+    "@ionic-native/in-app-browser": {
1701
+      "version": "5.35.0",
1702
+      "resolved": "https://registry.npmjs.org/@ionic-native/in-app-browser/-/in-app-browser-5.35.0.tgz",
1703
+      "integrity": "sha512-P06lB3ZhMPn1r5qT742uqczRfceY3dPAAAujlGD+m/06DSikKcB4CYDUHrowJbYAXYr8hkHtnQgtthZx5PPZAA==",
1704
+      "requires": {
1705
+        "@types/cordova": "^0.0.34"
1706
+      }
1707
+    },
1695 1708
     "@ionic/angular": {
1696 1709
       "version": "5.6.13",
1697 1710
       "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-5.6.13.tgz",
@@ -1994,6 +2007,25 @@
1994 2007
         "schema-utils": "^2.7.0"
1995 2008
       }
1996 2009
     },
2010
+    "@netflix/nerror": {
2011
+      "version": "1.1.3",
2012
+      "resolved": "https://registry.npmjs.org/@netflix/nerror/-/nerror-1.1.3.tgz",
2013
+      "integrity": "sha512-b+MGNyP9/LXkapreJzNUzcvuzZslj/RGgdVVJ16P2wSlYatfLycPObImqVJSmNAdyeShvNeM/pl3sVZsObFueg==",
2014
+      "dev": true,
2015
+      "requires": {
2016
+        "assert-plus": "^1.0.0",
2017
+        "extsprintf": "^1.4.0",
2018
+        "lodash": "^4.17.15"
2019
+      },
2020
+      "dependencies": {
2021
+        "extsprintf": {
2022
+          "version": "1.4.0",
2023
+          "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz",
2024
+          "integrity": "sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=",
2025
+          "dev": true
2026
+        }
2027
+      }
2028
+    },
1997 2029
     "@ngtools/webpack": {
1998 2030
       "version": "12.1.4",
1999 2031
       "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-12.1.4.tgz",
@@ -2133,6 +2165,11 @@
2133 2165
       "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==",
2134 2166
       "dev": true
2135 2167
     },
2168
+    "@types/cordova": {
2169
+      "version": "0.0.34",
2170
+      "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz",
2171
+      "integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ="
2172
+    },
2136 2173
     "@types/cors": {
2137 2174
       "version": "2.8.12",
2138 2175
       "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
@@ -2717,6 +2754,12 @@
2717 2754
       "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
2718 2755
       "dev": true
2719 2756
     },
2757
+    "ansi": {
2758
+      "version": "0.3.1",
2759
+      "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz",
2760
+      "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=",
2761
+      "dev": true
2762
+    },
2720 2763
     "ansi-colors": {
2721 2764
       "version": "4.1.1",
2722 2765
       "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
@@ -3186,8 +3229,7 @@
3186 3229
     "base64-js": {
3187 3230
       "version": "1.5.1",
3188 3231
       "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
3189
-      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
3190
-      "dev": true
3232
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
3191 3233
     },
3192 3234
     "base64id": {
3193 3235
       "version": "2.0.0",
@@ -3319,6 +3361,15 @@
3319 3361
       "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
3320 3362
       "dev": true
3321 3363
     },
3364
+    "bplist-creator": {
3365
+      "version": "0.0.8",
3366
+      "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.8.tgz",
3367
+      "integrity": "sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA==",
3368
+      "dev": true,
3369
+      "requires": {
3370
+        "stream-buffers": "~2.2.0"
3371
+      }
3372
+    },
3322 3373
     "bplist-parser": {
3323 3374
       "version": "0.2.0",
3324 3375
       "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz",
@@ -4162,6 +4213,126 @@
4162 4213
         }
4163 4214
       }
4164 4215
     },
4216
+    "cordova-common": {
4217
+      "version": "4.0.2",
4218
+      "resolved": "https://registry.npmjs.org/cordova-common/-/cordova-common-4.0.2.tgz",
4219
+      "integrity": "sha512-od7aNShyuBajzPY83mUEO8tERwwWdFklXETHiXP5Ft87CWeo/tSuwNPFztyTy8XYc74yXdogXKPTJeUHuVzB8Q==",
4220
+      "dev": true,
4221
+      "requires": {
4222
+        "@netflix/nerror": "^1.1.3",
4223
+        "ansi": "^0.3.1",
4224
+        "bplist-parser": "^0.2.0",
4225
+        "cross-spawn": "^7.0.1",
4226
+        "elementtree": "^0.1.7",
4227
+        "endent": "^1.4.1",
4228
+        "fast-glob": "^3.2.2",
4229
+        "fs-extra": "^9.0.0",
4230
+        "glob": "^7.1.6",
4231
+        "plist": "^3.0.1",
4232
+        "q": "^1.5.1",
4233
+        "read-chunk": "^3.2.0",
4234
+        "strip-bom": "^4.0.0",
4235
+        "underscore": "^1.9.2"
4236
+      },
4237
+      "dependencies": {
4238
+        "q": {
4239
+          "version": "1.5.1",
4240
+          "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
4241
+          "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
4242
+          "dev": true
4243
+        },
4244
+        "strip-bom": {
4245
+          "version": "4.0.0",
4246
+          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
4247
+          "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
4248
+          "dev": true
4249
+        }
4250
+      }
4251
+    },
4252
+    "cordova-ios": {
4253
+      "version": "6.2.0",
4254
+      "resolved": "https://registry.npmjs.org/cordova-ios/-/cordova-ios-6.2.0.tgz",
4255
+      "integrity": "sha512-sLjZg2QBI1SpQVwfe0MSn89YNVkBGLW9Q1vcFJBsqKBrhvoEOJ5Ytq0gwqdhgTOGzlwJUfxC6OHM3jcsRjtYrw==",
4256
+      "dev": true,
4257
+      "requires": {
4258
+        "cordova-common": "^4.0.2",
4259
+        "fs-extra": "^9.1.0",
4260
+        "ios-sim": "^8.0.2",
4261
+        "nopt": "^5.0.0",
4262
+        "plist": "^3.0.1",
4263
+        "semver": "^7.3.4",
4264
+        "unorm": "^1.6.0",
4265
+        "which": "^2.0.2",
4266
+        "xcode": "^3.0.1",
4267
+        "xml-escape": "^1.1.0"
4268
+      }
4269
+    },
4270
+    "cordova-plugin-browsertab": {
4271
+      "version": "0.2.0",
4272
+      "resolved": "https://registry.npmjs.org/cordova-plugin-browsertab/-/cordova-plugin-browsertab-0.2.0.tgz",
4273
+      "integrity": "sha1-Hgf5hy4VRnpQ59FKc/79h0+u1ko=",
4274
+      "dev": true
4275
+    },
4276
+    "cordova-plugin-compat": {
4277
+      "version": "1.2.0",
4278
+      "resolved": "https://registry.npmjs.org/cordova-plugin-compat/-/cordova-plugin-compat-1.2.0.tgz",
4279
+      "integrity": "sha1-C8ZXVyduvZIMASzpIOJ0F3V2Nz4=",
4280
+      "dev": true
4281
+    },
4282
+    "cordova-plugin-deeplinks": {
4283
+      "version": "1.1.1",
4284
+      "resolved": "https://registry.npmjs.org/cordova-plugin-deeplinks/-/cordova-plugin-deeplinks-1.1.1.tgz",
4285
+      "integrity": "sha512-njXvQj7OOF8t7/jYsUjJ3TA/5d7J4RNzgX93ZQoNhJ2/Ta3k7N5/AubR0a+UJ2F6/7c3U7oh4UgcXHwTqxA+ew==",
4286
+      "dev": true,
4287
+      "requires": {
4288
+        "mkpath": ">=1.0.0",
4289
+        "node-version-compare": ">=1.0.1",
4290
+        "plist": ">=1.2.0",
4291
+        "rimraf": ">=2.4",
4292
+        "xml2js": ">=0.4"
4293
+      }
4294
+    },
4295
+    "cordova-plugin-device": {
4296
+      "version": "2.0.2",
4297
+      "resolved": "https://registry.npmjs.org/cordova-plugin-device/-/cordova-plugin-device-2.0.2.tgz",
4298
+      "integrity": "sha1-/Ajzci5n7ve2xnv8mag99q3Quro=",
4299
+      "dev": true
4300
+    },
4301
+    "cordova-plugin-inappbrowser": {
4302
+      "version": "5.0.0",
4303
+      "resolved": "https://registry.npmjs.org/cordova-plugin-inappbrowser/-/cordova-plugin-inappbrowser-5.0.0.tgz",
4304
+      "integrity": "sha512-MqnpmUQ/iy6hxtIGDdlIhy8aNi1pNanLATpbnkk7uCqW9YQ4rH/dGK9zESbZ50pUi2A2D2QMjBXNV175TJK5OQ=="
4305
+    },
4306
+    "cordova-plugin-ionic-keyboard": {
4307
+      "version": "2.2.0",
4308
+      "resolved": "https://registry.npmjs.org/cordova-plugin-ionic-keyboard/-/cordova-plugin-ionic-keyboard-2.2.0.tgz",
4309
+      "integrity": "sha512-yDUG+9ieKVRitq5mGlNxjaZh/MgEhFFIgTIPhqSbUaQ8UuZbawy5mhJAVClqY97q8/rcQtL6dCDa7x2sEtCLcA==",
4310
+      "dev": true
4311
+    },
4312
+    "cordova-plugin-ionic-webview": {
4313
+      "version": "4.2.1",
4314
+      "resolved": "https://registry.npmjs.org/cordova-plugin-ionic-webview/-/cordova-plugin-ionic-webview-4.2.1.tgz",
4315
+      "integrity": "sha512-7KrmqLaOGq1RP8N2z1ezN1kqkWFzTwwMvQ3/qAkd+exxFZuOe3DIN4eaU1gdNphsxdirI8Ajnr9q4So5vQbWqw==",
4316
+      "dev": true
4317
+    },
4318
+    "cordova-plugin-splashscreen": {
4319
+      "version": "5.0.2",
4320
+      "resolved": "https://registry.npmjs.org/cordova-plugin-splashscreen/-/cordova-plugin-splashscreen-5.0.2.tgz",
4321
+      "integrity": "sha1-dH509W4gHNWFvGLRS8oZ9oZ/8e0=",
4322
+      "dev": true
4323
+    },
4324
+    "cordova-plugin-statusbar": {
4325
+      "version": "2.4.2",
4326
+      "resolved": "https://registry.npmjs.org/cordova-plugin-statusbar/-/cordova-plugin-statusbar-2.4.2.tgz",
4327
+      "integrity": "sha1-/B+9wNjXAzp+jh8ff/FnrJvU+vY=",
4328
+      "dev": true
4329
+    },
4330
+    "cordova-plugin-whitelist": {
4331
+      "version": "1.3.3",
4332
+      "resolved": "https://registry.npmjs.org/cordova-plugin-whitelist/-/cordova-plugin-whitelist-1.3.3.tgz",
4333
+      "integrity": "sha1-tehezbv+Wu3tQKG/TuI3LmfZb7Q=",
4334
+      "dev": true
4335
+    },
4165 4336
     "core-js": {
4166 4337
       "version": "3.15.1",
4167 4338
       "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.15.1.tgz",
@@ -4742,6 +4913,12 @@
4742 4913
       "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
4743 4914
       "dev": true
4744 4915
     },
4916
+    "dedent": {
4917
+      "version": "0.7.0",
4918
+      "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
4919
+      "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=",
4920
+      "dev": true
4921
+    },
4745 4922
     "deep-equal": {
4746 4923
       "version": "1.1.1",
4747 4924
       "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
@@ -5119,6 +5296,17 @@
5119 5296
         "once": "^1.4.0"
5120 5297
       }
5121 5298
     },
5299
+    "endent": {
5300
+      "version": "1.4.1",
5301
+      "resolved": "https://registry.npmjs.org/endent/-/endent-1.4.1.tgz",
5302
+      "integrity": "sha512-buHTb5c8AC9NshtP6dgmNLYkiT+olskbq1z6cEGvfGCF3Qphbu/1zz5Xu+yjTDln8RbxNhPoUyJ5H8MSrp1olQ==",
5303
+      "dev": true,
5304
+      "requires": {
5305
+        "dedent": "^0.7.0",
5306
+        "fast-json-parse": "^1.0.3",
5307
+        "objectorarray": "^1.0.4"
5308
+      }
5309
+    },
5122 5310
     "engine.io": {
5123 5311
       "version": "4.1.1",
5124 5312
       "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.1.tgz",
@@ -6065,6 +6253,12 @@
6065 6253
         }
6066 6254
       }
6067 6255
     },
6256
+    "fast-json-parse": {
6257
+      "version": "1.0.3",
6258
+      "resolved": "https://registry.npmjs.org/fast-json-parse/-/fast-json-parse-1.0.3.tgz",
6259
+      "integrity": "sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw==",
6260
+      "dev": true
6261
+    },
6068 6262
     "fast-json-stable-stringify": {
6069 6263
       "version": "2.1.0",
6070 6264
       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -7215,6 +7409,17 @@
7215 7409
         "side-channel": "^1.0.4"
7216 7410
       }
7217 7411
     },
7412
+    "ionic-plugin-deeplinks": {
7413
+      "version": "1.0.22",
7414
+      "resolved": "https://registry.npmjs.org/ionic-plugin-deeplinks/-/ionic-plugin-deeplinks-1.0.22.tgz",
7415
+      "integrity": "sha512-tdRMp9OIoXn3W2YG83TfvT048DwY+PkwUNKHqcDymBrC/Pk1+5ZYrrKKYFVD2x75x5zaZN+JBIaBrabXt8bC4w==",
7416
+      "requires": {
7417
+        "mkpath": ">=1.0.0",
7418
+        "node-version-compare": ">=1.0.1",
7419
+        "plist": ">=1.2.0",
7420
+        "xml2js": ">=0.4"
7421
+      }
7422
+    },
7218 7423
     "ionicons": {
7219 7424
       "version": "5.5.3",
7220 7425
       "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-5.5.3.tgz",
@@ -7223,6 +7428,35 @@
7223 7428
         "@stencil/core": "^2.5.0"
7224 7429
       }
7225 7430
     },
7431
+    "ios-sim": {
7432
+      "version": "8.0.2",
7433
+      "resolved": "https://registry.npmjs.org/ios-sim/-/ios-sim-8.0.2.tgz",
7434
+      "integrity": "sha512-P7nEG771bfd+JoMRjnis1gpZOkjTUUxu+4Ek1Z+eoaEEoT9byllU9pxfQ8Df7hL3gSkIQxNwTSLhos2I8tWUQA==",
7435
+      "dev": true,
7436
+      "requires": {
7437
+        "bplist-parser": "^0.0.6",
7438
+        "nopt": "1.0.9",
7439
+        "plist": "^3.0.1",
7440
+        "simctl": "^2"
7441
+      },
7442
+      "dependencies": {
7443
+        "bplist-parser": {
7444
+          "version": "0.0.6",
7445
+          "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.0.6.tgz",
7446
+          "integrity": "sha1-ONo0cYF9+dRKs4kuJ3B7u9daEbk=",
7447
+          "dev": true
7448
+        },
7449
+        "nopt": {
7450
+          "version": "1.0.9",
7451
+          "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.9.tgz",
7452
+          "integrity": "sha1-O8DXy6e/sNWmdtvtfA6+SKT9RU4=",
7453
+          "dev": true,
7454
+          "requires": {
7455
+            "abbrev": "1"
7456
+          }
7457
+        }
7458
+      }
7459
+    },
7226 7460
     "ip": {
7227 7461
       "version": "1.1.5",
7228 7462
       "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
@@ -7752,6 +7986,11 @@
7752 7986
         }
7753 7987
       }
7754 7988
     },
7989
+    "js-sha256": {
7990
+      "version": "0.9.0",
7991
+      "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz",
7992
+      "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA=="
7993
+    },
7755 7994
     "js-tokens": {
7756 7995
       "version": "4.0.0",
7757 7996
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -8132,6 +8371,30 @@
8132 8371
         "source-map-support": "^0.5.5"
8133 8372
       }
8134 8373
     },
8374
+    "keycloak-angular": {
8375
+      "version": "8.3.0",
8376
+      "resolved": "https://registry.npmjs.org/keycloak-angular/-/keycloak-angular-8.3.0.tgz",
8377
+      "integrity": "sha512-N5vPAkiU8ujGhr5mogLvWNkoIuK98BuoZ9rPrwT/Wlq8sWbM7pTa7s6iBSb/bji2y4wnKAnh1HyytNa+v0TuYg==",
8378
+      "requires": {
8379
+        "tslib": "^2.0.0"
8380
+      }
8381
+    },
8382
+    "keycloak-js": {
8383
+      "version": "15.0.1",
8384
+      "resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-15.0.1.tgz",
8385
+      "integrity": "sha512-5WBbdZhP39E9nsDJ44P8h1lvQTQawVcydew93fBBoKdSOUmhFPxmcKGS7WwxXqhbVEBe3burdZTFSPzTXfY0ZQ==",
8386
+      "requires": {
8387
+        "base64-js": "1.3.1",
8388
+        "js-sha256": "0.9.0"
8389
+      },
8390
+      "dependencies": {
8391
+        "base64-js": {
8392
+          "version": "1.3.1",
8393
+          "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
8394
+          "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
8395
+        }
8396
+      }
8397
+    },
8135 8398
     "killable": {
8136 8399
       "version": "1.0.1",
8137 8400
       "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@@ -8833,6 +9096,11 @@
8833 9096
       "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
8834 9097
       "dev": true
8835 9098
     },
9099
+    "mkpath": {
9100
+      "version": "1.0.0",
9101
+      "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-1.0.0.tgz",
9102
+      "integrity": "sha1-67Opd+evHGg65v2hK1Raa6bFhT0="
9103
+    },
8836 9104
     "ms": {
8837 9105
       "version": "2.1.2",
8838 9106
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -9005,6 +9273,11 @@
9005 9273
       "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==",
9006 9274
       "dev": true
9007 9275
     },
9276
+    "node-version-compare": {
9277
+      "version": "1.0.3",
9278
+      "resolved": "https://registry.npmjs.org/node-version-compare/-/node-version-compare-1.0.3.tgz",
9279
+      "integrity": "sha512-unO5GpBAh5YqeGULMLpmDT94oanSDMwtZB8KHTKCH/qrGv8bHN0mlDj9xQDAicCYXv2OLnzdi67lidCrcVotVw=="
9280
+    },
9008 9281
     "nopt": {
9009 9282
       "version": "5.0.0",
9010 9283
       "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
@@ -9287,6 +9560,12 @@
9287 9560
         "es-abstract": "^1.18.2"
9288 9561
       }
9289 9562
     },
9563
+    "objectorarray": {
9564
+      "version": "1.0.5",
9565
+      "resolved": "https://registry.npmjs.org/objectorarray/-/objectorarray-1.0.5.tgz",
9566
+      "integrity": "sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg==",
9567
+      "dev": true
9568
+    },
9290 9569
     "obuf": {
9291 9570
       "version": "1.1.2",
9292 9571
       "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
@@ -9686,7 +9965,6 @@
9686 9965
       "version": "3.0.3",
9687 9966
       "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.3.tgz",
9688 9967
       "integrity": "sha512-ghdOKN99hh1oEmAlwBmPYo4L+tSQ7O3jRpkhWqOrMz86CWotpVzMevvQ+czo7oPDpOZyA6K06Ci7QVHpoh9gaA==",
9689
-      "dev": true,
9690 9968
       "requires": {
9691 9969
         "base64-js": "^1.5.1",
9692 9970
         "xmlbuilder": "^9.0.7",
@@ -11800,6 +12078,16 @@
11800 12078
         }
11801 12079
       }
11802 12080
     },
12081
+    "read-chunk": {
12082
+      "version": "3.2.0",
12083
+      "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-3.2.0.tgz",
12084
+      "integrity": "sha512-CEjy9LCzhmD7nUpJ1oVOE6s/hBkejlcJEgLQHVnQznOSilOPb+kpKktlLfFDK3/WP43+F80xkUTM2VOkYoSYvQ==",
12085
+      "dev": true,
12086
+      "requires": {
12087
+        "pify": "^4.0.1",
12088
+        "with-open-file": "^0.1.6"
12089
+      }
12090
+    },
11803 12091
     "read-package-json-fast": {
11804 12092
       "version": "2.0.3",
11805 12093
       "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz",
@@ -12355,8 +12643,7 @@
12355 12643
     "sax": {
12356 12644
       "version": "1.1.4",
12357 12645
       "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.4.tgz",
12358
-      "integrity": "sha1-dLbTPJrh4AFRDxeakRaFiPGu2qk=",
12359
-      "dev": true
12646
+      "integrity": "sha1-dLbTPJrh4AFRDxeakRaFiPGu2qk="
12360 12647
     },
12361 12648
     "schema-utils": {
12362 12649
       "version": "2.7.1",
@@ -12633,6 +12920,12 @@
12633 12920
       "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
12634 12921
       "dev": true
12635 12922
     },
12923
+    "shelljs": {
12924
+      "version": "0.2.6",
12925
+      "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.2.6.tgz",
12926
+      "integrity": "sha1-kEktcv/MgVmXa6umL7D2iE8MM3g=",
12927
+      "dev": true
12928
+    },
12636 12929
     "side-channel": {
12637 12930
       "version": "1.0.4",
12638 12931
       "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@@ -12650,6 +12943,27 @@
12650 12943
       "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
12651 12944
       "dev": true
12652 12945
     },
12946
+    "simctl": {
12947
+      "version": "2.0.0",
12948
+      "resolved": "https://registry.npmjs.org/simctl/-/simctl-2.0.0.tgz",
12949
+      "integrity": "sha512-5rB7rN4N3b0z0nFdy9eczVssXqrv2aAgdVRksPVqVoiDtvXmfzNvebp3EMdId2sAUzXIflarQlx4P0hjVQEzKQ==",
12950
+      "dev": true,
12951
+      "requires": {
12952
+        "shelljs": "^0.2.6",
12953
+        "tail": "^0.4.0"
12954
+      }
12955
+    },
12956
+    "simple-plist": {
12957
+      "version": "1.1.1",
12958
+      "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.1.1.tgz",
12959
+      "integrity": "sha512-pKMCVKvZbZTsqYR6RKgLfBHkh2cV89GXcA/0CVPje3sOiNOnXA8+rp/ciAMZ7JRaUdLzlEM6JFfUn+fS6Nt3hg==",
12960
+      "dev": true,
12961
+      "requires": {
12962
+        "bplist-creator": "0.0.8",
12963
+        "bplist-parser": "0.2.0",
12964
+        "plist": "^3.0.1"
12965
+      }
12966
+    },
12653 12967
     "sisteransi": {
12654 12968
       "version": "1.0.5",
12655 12969
       "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
@@ -13133,6 +13447,12 @@
13133 13447
       "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
13134 13448
       "dev": true
13135 13449
     },
13450
+    "stream-buffers": {
13451
+      "version": "2.2.0",
13452
+      "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz",
13453
+      "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=",
13454
+      "dev": true
13455
+    },
13136 13456
     "streamroller": {
13137 13457
       "version": "2.2.4",
13138 13458
       "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz",
@@ -13429,6 +13749,12 @@
13429 13749
         "strip-ansi": "^6.0.0"
13430 13750
       }
13431 13751
     },
13752
+    "tail": {
13753
+      "version": "0.4.0",
13754
+      "resolved": "https://registry.npmjs.org/tail/-/tail-0.4.0.tgz",
13755
+      "integrity": "sha1-0p3nJ1DMmdseBTr/E8NZ7PtxMAI=",
13756
+      "dev": true
13757
+    },
13432 13758
     "tapable": {
13433 13759
       "version": "2.2.0",
13434 13760
       "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz",
@@ -13749,6 +14075,12 @@
13749 14075
         "which-boxed-primitive": "^1.0.2"
13750 14076
       }
13751 14077
     },
14078
+    "underscore": {
14079
+      "version": "1.13.1",
14080
+      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz",
14081
+      "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==",
14082
+      "dev": true
14083
+    },
13752 14084
     "unicode-canonical-property-names-ecmascript": {
13753 14085
       "version": "1.0.4",
13754 14086
       "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
@@ -13825,6 +14157,12 @@
13825 14157
       "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
13826 14158
       "dev": true
13827 14159
     },
14160
+    "unorm": {
14161
+      "version": "1.6.0",
14162
+      "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
14163
+      "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==",
14164
+      "dev": true
14165
+    },
13828 14166
     "unpipe": {
13829 14167
       "version": "1.0.0",
13830 14168
       "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@@ -14675,6 +15013,17 @@
14675 15013
       "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
14676 15014
       "dev": true
14677 15015
     },
15016
+    "with-open-file": {
15017
+      "version": "0.1.7",
15018
+      "resolved": "https://registry.npmjs.org/with-open-file/-/with-open-file-0.1.7.tgz",
15019
+      "integrity": "sha512-ecJS2/oHtESJ1t3ZfMI3B7KIDKyfN0O16miWxdn30zdh66Yd3LsRFebXZXq6GU4xfxLf6nVxp9kIqElb5fqczA==",
15020
+      "dev": true,
15021
+      "requires": {
15022
+        "p-finally": "^1.0.0",
15023
+        "p-try": "^2.1.0",
15024
+        "pify": "^4.0.1"
15025
+      }
15026
+    },
14678 15027
     "word-wrap": {
14679 15028
       "version": "1.2.3",
14680 15029
       "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
@@ -14707,11 +15056,34 @@
14707 15056
         "async-limiter": "~1.0.0"
14708 15057
       }
14709 15058
     },
15059
+    "xcode": {
15060
+      "version": "3.0.1",
15061
+      "resolved": "https://registry.npmjs.org/xcode/-/xcode-3.0.1.tgz",
15062
+      "integrity": "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==",
15063
+      "dev": true,
15064
+      "requires": {
15065
+        "simple-plist": "^1.1.0",
15066
+        "uuid": "^7.0.3"
15067
+      },
15068
+      "dependencies": {
15069
+        "uuid": {
15070
+          "version": "7.0.3",
15071
+          "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz",
15072
+          "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==",
15073
+          "dev": true
15074
+        }
15075
+      }
15076
+    },
15077
+    "xml-escape": {
15078
+      "version": "1.1.0",
15079
+      "resolved": "https://registry.npmjs.org/xml-escape/-/xml-escape-1.1.0.tgz",
15080
+      "integrity": "sha1-OQTBQ/qOs6ADDsZG0pAqLxtwbEQ=",
15081
+      "dev": true
15082
+    },
14710 15083
     "xml2js": {
14711 15084
       "version": "0.4.23",
14712 15085
       "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
14713 15086
       "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
14714
-      "dev": true,
14715 15087
       "requires": {
14716 15088
         "sax": ">=0.6.0",
14717 15089
         "xmlbuilder": "~11.0.0"
@@ -14720,22 +15092,19 @@
14720 15092
         "xmlbuilder": {
14721 15093
           "version": "11.0.1",
14722 15094
           "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
14723
-          "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
14724
-          "dev": true
15095
+          "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
14725 15096
         }
14726 15097
       }
14727 15098
     },
14728 15099
     "xmlbuilder": {
14729 15100
       "version": "9.0.7",
14730 15101
       "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
14731
-      "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
14732
-      "dev": true
15102
+      "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
14733 15103
     },
14734 15104
     "xmldom": {
14735 15105
       "version": "0.6.0",
14736 15106
       "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz",
14737
-      "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==",
14738
-      "dev": true
15107
+      "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg=="
14739 15108
     },
14740 15109
     "y18n": {
14741 15110
       "version": "4.0.3",

+ 34
- 3
package.json Просмотреть файл

@@ -5,8 +5,8 @@
5 5
   "homepage": "https://ionicframework.com/",
6 6
   "scripts": {
7 7
     "ng": "ng",
8
-    "start": "ng serve",
9
-    "build": "ng build",
8
+    "start": "ng serve -c local",
9
+    "build": "ng build -c production --prod",
10 10
     "test": "ng test",
11 11
     "lint": "ng lint",
12 12
     "e2e": "ng e2e"
@@ -23,9 +23,15 @@
23 23
     "@capacitor/app": "1.0.2",
24 24
     "@capacitor/core": "3.1.2",
25 25
     "@capacitor/haptics": "1.0.2",
26
+    "@capacitor/ios": "3.1.2",
26 27
     "@capacitor/keyboard": "1.0.2",
27 28
     "@capacitor/status-bar": "1.0.2",
29
+    "@ionic-native/in-app-browser": "^5.35.0",
28 30
     "@ionic/angular": "^5.5.2",
31
+    "cordova-plugin-inappbrowser": "^5.0.0",
32
+    "ionic-plugin-deeplinks": "^1.0.22",
33
+    "keycloak-angular": "^8.3.0",
34
+    "keycloak-js": "^15.0.0",
29 35
     "rxjs": "~6.6.0",
30 36
     "tslib": "^2.2.0",
31 37
     "zone.js": "~0.11.4"
@@ -47,6 +53,16 @@
47 53
     "@types/node": "^12.11.1",
48 54
     "@typescript-eslint/eslint-plugin": "4.16.1",
49 55
     "@typescript-eslint/parser": "4.16.1",
56
+    "cordova-ios": "^6.2.0",
57
+    "cordova-plugin-browsertab": "^0.2.0",
58
+    "cordova-plugin-compat": "^1.2.0",
59
+    "cordova-plugin-deeplinks": "^1.1.1",
60
+    "cordova-plugin-device": "^2.0.2",
61
+    "cordova-plugin-ionic-keyboard": "^2.2.0",
62
+    "cordova-plugin-ionic-webview": "^4.2.1",
63
+    "cordova-plugin-splashscreen": "^5.0.2",
64
+    "cordova-plugin-statusbar": "^2.4.2",
65
+    "cordova-plugin-whitelist": "^1.3.3",
50 66
     "eslint": "^7.6.0",
51 67
     "eslint-plugin-import": "2.22.1",
52 68
     "eslint-plugin-jsdoc": "30.7.6",
@@ -63,5 +79,20 @@
63 79
     "ts-node": "~8.3.0",
64 80
     "typescript": "~4.2.4"
65 81
   },
66
-  "description": "An Ionic project"
82
+  "description": "An Ionic project",
83
+  "cordova": {
84
+    "plugins": {
85
+      "cordova-plugin-deeplinks": {},
86
+      "cordova-plugin-browsertab": {},
87
+      "cordova-plugin-whitelist": {},
88
+      "cordova-plugin-statusbar": {},
89
+      "cordova-plugin-device": {},
90
+      "cordova-plugin-splashscreen": {},
91
+      "cordova-plugin-ionic-webview": {},
92
+      "cordova-plugin-ionic-keyboard": {}
93
+    },
94
+    "platforms": [
95
+      "ios"
96
+    ]
97
+  }
67 98
 }

+ 7
- 1
src/app/app-routing.module.ts Просмотреть файл

@@ -1,10 +1,16 @@
1 1
 import { NgModule } from '@angular/core';
2 2
 import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
3
+import { AuthGuard } from './guard/auth.guard';
3 4
 
4 5
 const routes: Routes = [
5 6
   {
6 7
     path: '',
7
-    loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule)
8
+    loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule),
9
+    canActivate: [AuthGuard]
10
+  },
11
+  {
12
+    path: 'login',
13
+    loadChildren: () => import('./login/login.module').then( m => m.LoginPageModule)
8 14
   }
9 15
 ];
10 16
 @NgModule({

+ 26
- 4
src/app/app.module.ts Просмотреть файл

@@ -1,17 +1,39 @@
1
-import { NgModule } from '@angular/core';
1
+import { APP_INITIALIZER, NgModule } from '@angular/core';
2 2
 import { BrowserModule } from '@angular/platform-browser';
3 3
 import { RouteReuseStrategy } from '@angular/router';
4 4
 
5
-import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
5
+import { IonicModule, IonicRouteStrategy, Platform } from '@ionic/angular';
6
+import { KeycloakAngularModule } from 'keycloak-angular';
6 7
 
7 8
 import { AppRoutingModule } from './app-routing.module';
8 9
 import { AppComponent } from './app.component';
10
+import { AppInitializer } from './init/keycloak-initializer.factory';
11
+import { AuthProviderService } from './services/keycloak/auth-provider.service';
9 12
 
10 13
 @NgModule({
11 14
   declarations: [AppComponent],
12 15
   entryComponents: [],
13
-  imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
14
-  providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
16
+  imports: [
17
+    BrowserModule, 
18
+    IonicModule.forRoot(), 
19
+    AppRoutingModule,
20
+    KeycloakAngularModule
21
+  ],
22
+  providers: [
23
+    {
24
+      provide: APP_INITIALIZER,
25
+      useFactory: AppInitializer,
26
+      deps: [
27
+        AuthProviderService,
28
+        Platform
29
+      ],
30
+      multi: true
31
+    },
32
+    { 
33
+      provide: RouteReuseStrategy, 
34
+      useClass: IonicRouteStrategy 
35
+    }
36
+  ],
15 37
   bootstrap: [AppComponent],
16 38
 })
17 39
 export class AppModule {}

+ 36
- 0
src/app/guard/auth.guard.ts Просмотреть файл

@@ -0,0 +1,36 @@
1
+import { Injectable } from '@angular/core';
2
+import { ActivatedRouteSnapshot, Router, RouterStateSnapshot, UrlTree } from '@angular/router';
3
+import { KeycloakAuthGuard } from 'keycloak-angular';
4
+import { AuthProviderService } from '../services/keycloak/auth-provider.service';
5
+
6
+@Injectable({
7
+  providedIn: 'root'
8
+})
9
+export class AuthGuard extends KeycloakAuthGuard {
10
+
11
+  constructor(
12
+    protected router: Router,
13
+    protected readonly authProviderService: AuthProviderService) {
14
+    super(router, authProviderService.getProvider());
15
+  }
16
+  
17
+  /**
18
+   * Permet de vérifier l'accès/l'authification de l'utilisateur
19
+   * 
20
+   * @param route 
21
+   * @param state 
22
+   * @returns Promise
23
+   */
24
+  async isAccessAllowed(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean | UrlTree> {
25
+    if (!this.authenticated) {
26
+      console.log('Not authenticated. Redirect to login page ...');
27
+      this.router.navigateByUrl('/login');
28
+      // await this.authProviderService.getProvider().login({
29
+      //   redirectUri: window.location.origin + state.url,
30
+      // });
31
+    }
32
+    
33
+    return this.authenticated;
34
+  }
35
+  
36
+}

+ 34
- 0
src/app/init/keycloak-initializer.factory.ts Просмотреть файл

@@ -0,0 +1,34 @@
1
+import { Platform } from "@ionic/angular";
2
+import { AuthProviderService } from "../services/keycloak/auth-provider.service";
3
+
4
+
5
+function initializeKeycloak(authProviderService: AuthProviderService, platform: Platform): Promise<any> {
6
+  return new Promise(async (resolve, reject) => {
7
+    platform.ready().then(async ready => {
8
+      try {
9
+        const loggedIn = await authProviderService.getProvider().isLoggedIn();
10
+        console.log('Initializing keycloak ...', loggedIn);
11
+        //  authProviderService.init().then(sucess => {
12
+        //    console.log("logging succeed...", sucess);
13
+        //    resolve('Authentication succeeded ...');
14
+        //  }).catch(error => {
15
+        //     console.log('Somehting may be wrong somehow...');
16
+        //     reject(error);
17
+        //  });
18
+        await authProviderService.init();
19
+        console.log('Getting access token ...');
20
+        // await authProviderService.getToken();
21
+        resolve('Authentication succeeded ...');
22
+      } catch (error) {
23
+        console.log('Failed to initialize Keycloak...', error);
24
+        reject(error);
25
+      }
26
+    });
27
+  });
28
+}
29
+
30
+export function AppInitializer(authProviderService: AuthProviderService, platform: Platform): () => Promise<any> {
31
+  return (): Promise<any> => {
32
+    return initializeKeycloak(authProviderService, platform);
33
+  };
34
+}

+ 17
- 0
src/app/login/login-routing.module.ts Просмотреть файл

@@ -0,0 +1,17 @@
1
+import { NgModule } from '@angular/core';
2
+import { Routes, RouterModule } from '@angular/router';
3
+
4
+import { LoginPage } from './login.page';
5
+
6
+const routes: Routes = [
7
+  {
8
+    path: '',
9
+    component: LoginPage
10
+  }
11
+];
12
+
13
+@NgModule({
14
+  imports: [RouterModule.forChild(routes)],
15
+  exports: [RouterModule],
16
+})
17
+export class LoginPageRoutingModule {}

+ 20
- 0
src/app/login/login.module.ts Просмотреть файл

@@ -0,0 +1,20 @@
1
+import { NgModule } from '@angular/core';
2
+import { CommonModule } from '@angular/common';
3
+import { FormsModule } from '@angular/forms';
4
+
5
+import { IonicModule } from '@ionic/angular';
6
+
7
+import { LoginPageRoutingModule } from './login-routing.module';
8
+
9
+import { LoginPage } from './login.page';
10
+
11
+@NgModule({
12
+  imports: [
13
+    CommonModule,
14
+    FormsModule,
15
+    IonicModule,
16
+    LoginPageRoutingModule
17
+  ],
18
+  declarations: [LoginPage]
19
+})
20
+export class LoginPageModule {}

+ 12
- 0
src/app/login/login.page.html Просмотреть файл

@@ -0,0 +1,12 @@
1
+<ion-header>
2
+  <ion-toolbar>
3
+    <ion-title>login</ion-title>
4
+  </ion-toolbar>
5
+</ion-header>
6
+
7
+<ion-content>
8
+  <p style="text-align:center">Please sign into your account:</p>
9
+  <ion-button expand="block" (click)="login()" padding size="large">
10
+    Log In
11
+  </ion-button>
12
+</ion-content>

+ 0
- 0
src/app/login/login.page.scss Просмотреть файл


+ 24
- 0
src/app/login/login.page.spec.ts Просмотреть файл

@@ -0,0 +1,24 @@
1
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2
+import { IonicModule } from '@ionic/angular';
3
+
4
+import { LoginPage } from './login.page';
5
+
6
+describe('LoginPage', () => {
7
+  let component: LoginPage;
8
+  let fixture: ComponentFixture<LoginPage>;
9
+
10
+  beforeEach(waitForAsync(() => {
11
+    TestBed.configureTestingModule({
12
+      declarations: [ LoginPage ],
13
+      imports: [IonicModule.forRoot()]
14
+    }).compileComponents();
15
+
16
+    fixture = TestBed.createComponent(LoginPage);
17
+    component = fixture.componentInstance;
18
+    fixture.detectChanges();
19
+  }));
20
+
21
+  it('should create', () => {
22
+    expect(component).toBeTruthy();
23
+  });
24
+});

+ 27
- 0
src/app/login/login.page.ts Просмотреть файл

@@ -0,0 +1,27 @@
1
+import { Component, OnInit } from '@angular/core';
2
+import { Router } from '@angular/router';
3
+import { AuthProviderService } from '../services/keycloak/auth-provider.service';
4
+
5
+@Component({
6
+  selector: 'app-login',
7
+  templateUrl: './login.page.html',
8
+  styleUrls: ['./login.page.scss'],
9
+})
10
+export class LoginPage implements OnInit {
11
+
12
+  constructor(private authProviderService: AuthProviderService,
13
+    private router: Router) { }
14
+
15
+  ngOnInit() {
16
+  }
17
+
18
+  login() {
19
+    this.authProviderService.getProvider().login().then(sucess => {
20
+      console.log('Login success', sucess);
21
+      this.router.navigateByUrl('/tabs/tab3');
22
+    }).catch(error => {
23
+      console.log('Error on login', error)
24
+    });
25
+  }
26
+
27
+}

+ 16
- 0
src/app/services/keycloak/auth-provider.service.spec.ts Просмотреть файл

@@ -0,0 +1,16 @@
1
+import { TestBed } from '@angular/core/testing';
2
+
3
+import { AuthProviderService } from './auth-provider.service';
4
+
5
+describe('AuthProviderService', () => {
6
+  let service: AuthProviderService;
7
+
8
+  beforeEach(() => {
9
+    TestBed.configureTestingModule({});
10
+    service = TestBed.inject(AuthProviderService);
11
+  });
12
+
13
+  it('should be created', () => {
14
+    expect(service).toBeTruthy();
15
+  });
16
+});

+ 79
- 0
src/app/services/keycloak/auth-provider.service.ts Просмотреть файл

@@ -0,0 +1,79 @@
1
+import { Injectable } from '@angular/core';
2
+import { Platform } from '@ionic/angular';
3
+import { KeycloakService } from 'keycloak-angular';
4
+import { environment } from 'src/environments/environment';
5
+import { KEYCLOAK_CONFIG_LOCAL_URL, KEYCLOAK_CONFIG_URL, LOGIN_REQUIRED, SILENT_CHECK_SSO } from 'src/shared/constants';
6
+
7
+@Injectable({
8
+  providedIn: 'root'
9
+})
10
+export class AuthProviderService {
11
+  private keycloakConfigFile: any;
12
+
13
+  constructor(private keycloakService: KeycloakService,
14
+    private platform: Platform) { 
15
+   this.keycloakConfigFile = environment.production ? KEYCLOAK_CONFIG_URL
16
+     : KEYCLOAK_CONFIG_LOCAL_URL;
17
+  }
18
+
19
+  /**
20
+   * Méthode d'initialisation Keycloak
21
+   * utilise la méthode par défaut de la lib keycloak-js (keycloak-angular)
22
+   * 
23
+   * @returns Promise
24
+   */
25
+  init(): Promise<boolean> {
26
+    console.log(this.keycloakConfigFile);
27
+    return this.keycloakService.init({
28
+      config: this.keycloakConfigFile,
29
+      initOptions: {
30
+        adapter: 'cordova',
31
+        onLoad: 'check-sso',
32
+        checkLoginIframe: true,
33
+        enableLogging: true,
34
+        // redirectUri: 'mynatan-ionic-keycloak://app'
35
+        // silentCheckSsoFallback: false,
36
+        silentCheckSsoRedirectUri: SILENT_CHECK_SSO
37
+      },
38
+      // bearerExcludedUrls: ['test$'],
39
+      enableBearerInterceptor: false
40
+    });
41
+  }
42
+
43
+  /**
44
+   * Getter du service keycloak
45
+   * 
46
+   * @returns KeycloakService
47
+   */
48
+  getProvider(): KeycloakService {
49
+    return this.keycloakService;
50
+  }
51
+
52
+  /**
53
+   * Recupere le token keycloak
54
+   * 
55
+   * @returns Promise
56
+   */
57
+  getToken(): Promise<any> {
58
+    return new Promise((resolve, reject) => {
59
+      this.keycloakService.getToken()
60
+        .then(token => {
61
+          // this.storageService.store('authenticationToken', token);
62
+          resolve(token);
63
+        })
64
+        .catch(reason => {
65
+          console.log('Failed to get token', reason);
66
+          reject(reason);
67
+        });
68
+    });
69
+  }
70
+  
71
+  /**
72
+   * Méthode de deconnexion de keycloak
73
+   * 
74
+   * @returns 
75
+   */
76
+  logout(): Promise<any>{
77
+    return this.keycloakService.logout();
78
+  }
79
+}

+ 1
- 1
src/app/tab3/tab3.page.html Просмотреть файл

@@ -13,5 +13,5 @@
13 13
     </ion-toolbar>
14 14
   </ion-header>
15 15
 
16
-  <app-explore-container name="Tab 3 page"></app-explore-container>
16
+  <app-explore-container *ngIf="userProfile" name="Tab 3 page {{userProfile.username}}"></app-explore-container>
17 17
 </ion-content>

+ 18
- 3
src/app/tab3/tab3.page.ts Просмотреть файл

@@ -1,12 +1,27 @@
1
-import { Component } from '@angular/core';
1
+import { Component, OnInit } from '@angular/core';
2
+import { AuthProviderService } from '../services/keycloak/auth-provider.service';
2 3
 
3 4
 @Component({
4 5
   selector: 'app-tab3',
5 6
   templateUrl: 'tab3.page.html',
6 7
   styleUrls: ['tab3.page.scss']
7 8
 })
8
-export class Tab3Page {
9
+export class Tab3Page implements OnInit {
10
+  userProfile: any;
11
+  constructor(private authProviderService: AuthProviderService) {}
9 12
 
10
-  constructor() {}
13
+  ngOnInit(): void {
14
+    this.getUserInfo();
15
+  }
16
+
17
+  getUserInfo() {
18
+    this.authProviderService.getProvider().loadUserProfile()
19
+      .then(profile => {
20
+        this.userProfile = profile;
21
+        console.log('User profile', this.userProfile);
22
+      }).catch(error => {
23
+        console.log('Error getting user profile', error);
24
+      });
25
+  }
11 26
 
12 27
 }

+ 8
- 0
src/assets/conf/keycloak-local.json Просмотреть файл

@@ -0,0 +1,8 @@
1
+{
2
+  "realm": "master",
3
+  "auth-server-url": "http://192.168.1.24:8080/auth/",
4
+  "ssl-required": "external",
5
+  "resource": "chrome-extension-angular-local",
6
+  "public-client": true,
7
+  "confidential-port": 0
8
+}

+ 8
- 0
src/assets/conf/keycloak.json Просмотреть файл

@@ -0,0 +1,8 @@
1
+{
2
+  "realm": "master",
3
+  "auth-server-url": "http://192.168.1.24:8080/auth/",
4
+  "ssl-required": "external",
5
+  "resource": "chrome-extension-angular-local",
6
+  "public-client": true,
7
+  "confidential-port": 0
8
+}

+ 7
- 0
src/assets/silent/silent-check-sso.html Просмотреть файл

@@ -0,0 +1,7 @@
1
+<html>
2
+  <body>
3
+    <script>
4
+      parent.postMessage(location.href, location.origin);
5
+    </script>
6
+  </body>
7
+</html>

+ 4
- 0
src/shared/constants.ts Просмотреть файл

@@ -0,0 +1,4 @@
1
+export const KEYCLOAK_CONFIG_LOCAL_URL = '/assets/conf/keycloak-local.json';
2
+export const KEYCLOAK_CONFIG_URL = '/assets/config/keycloak.json';
3
+export const LOGIN_REQUIRED = 'login-required';
4
+export const SILENT_CHECK_SSO = '/assets/silent/silent-check-sso.html';

+ 14
- 0
ul_web_hooks/ios/localhost#apple-app-site-association Просмотреть файл

@@ -0,0 +1,14 @@
1
+{
2
+  "applinks": {
3
+    "apps": [],
4
+    "details": [
5
+      {
6
+        "appID": "<YOUR_TEAM_ID_FROM_MEMBER_CENTER>.io.ionic.starter",
7
+        "paths": [
8
+          "*",
9
+          "/"
10
+        ]
11
+      }
12
+    ]
13
+  }
14
+}

Powered by TurnKey Linux.