├── .github └── workflows │ └── npmpublish.yml ├── .gitignore ├── .npmignore ├── .npmrc ├── CHANGELOG.md ├── CodetrixStudioCapacitorGoogleAuth.podspec ├── LICENSE ├── README.md ├── android ├── .npmignore ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── proguard-rules.pro ├── settings.gradle └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── getcapacitor │ │ └── android │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── codetrixstudio │ │ │ └── capacitor │ │ │ └── GoogleAuth │ │ │ └── GoogleAuth.java │ └── res │ │ ├── layout │ │ └── bridge_layout_main.xml │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── getcapacitor │ └── ExampleUnitTest.java ├── demo-ionic-angular ├── .browserslistrc ├── .editorconfig ├── .eslintrc.json ├── .gitignore ├── .vscode │ └── extensions.json ├── README.md ├── angular.json ├── capacitor.config.ts ├── ionic.config.json ├── karma.conf.js ├── package-lock.json ├── package.json ├── src │ ├── app │ │ ├── app-routing.module.ts │ │ ├── app.component.html │ │ ├── app.component.scss │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ └── home │ │ │ ├── home-routing.module.ts │ │ │ ├── home.module.ts │ │ │ ├── home.page.html │ │ │ ├── home.page.scss │ │ │ ├── home.page.spec.ts │ │ │ └── home.page.ts │ ├── assets │ │ ├── icon │ │ │ └── favicon.png │ │ └── shapes.svg │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── global.scss │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── test.ts │ ├── theme │ │ └── variables.scss │ └── zone-flags.ts ├── tsconfig.app.json ├── tsconfig.json └── tsconfig.spec.json ├── demo ├── .editorconfig ├── .gitignore ├── README.md ├── android │ ├── .gitignore │ ├── .idea │ │ ├── codeStyles │ │ │ └── Project.xml │ │ ├── encodings.xml │ │ ├── misc.xml │ │ └── runConfigurations.xml │ ├── app │ │ ├── .npmignore │ │ ├── build.gradle │ │ ├── capacitor.build.gradle │ │ ├── google-services.json │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── androidTest │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── getcapacitor │ │ │ │ └── myapp │ │ │ │ └── ExampleInstrumentedTest.java │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── assets │ │ │ │ └── capacitor.config.json │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── app │ │ │ │ │ └── MainActivity.java │ │ │ └── res │ │ │ │ ├── drawable-land-hdpi │ │ │ │ └── splash.png │ │ │ │ ├── drawable-land-mdpi │ │ │ │ └── splash.png │ │ │ │ ├── drawable-land-xhdpi │ │ │ │ └── splash.png │ │ │ │ ├── drawable-land-xxhdpi │ │ │ │ └── splash.png │ │ │ │ ├── drawable-land-xxxhdpi │ │ │ │ └── splash.png │ │ │ │ ├── drawable-port-hdpi │ │ │ │ └── splash.png │ │ │ │ ├── drawable-port-mdpi │ │ │ │ └── splash.png │ │ │ │ ├── drawable-port-xhdpi │ │ │ │ └── splash.png │ │ │ │ ├── drawable-port-xxhdpi │ │ │ │ └── splash.png │ │ │ │ ├── drawable-port-xxxhdpi │ │ │ │ └── splash.png │ │ │ │ ├── drawable-v24 │ │ │ │ └── ic_launcher_foreground.xml │ │ │ │ ├── drawable │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ ├── launch_splash.xml │ │ │ │ └── splash.png │ │ │ │ ├── layout │ │ │ │ └── activity_main.xml │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── values │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ │ └── xml │ │ │ │ ├── config.xml │ │ │ │ └── file_paths.xml │ │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── getcapacitor │ │ │ └── myapp │ │ │ └── ExampleUnitTest.java │ ├── build.gradle │ ├── capacitor.settings.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── angular.json ├── browserslist ├── capacitor.config.json ├── e2e │ ├── protractor.conf.js │ ├── src │ │ ├── app.e2e-spec.ts │ │ └── app.po.ts │ └── tsconfig.json ├── ios │ ├── .gitignore │ └── App │ │ ├── App.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ ├── App.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── App │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── AppIcon-20x20@1x.png │ │ │ │ ├── AppIcon-20x20@2x-1.png │ │ │ │ ├── AppIcon-20x20@2x.png │ │ │ │ ├── AppIcon-20x20@3x.png │ │ │ │ ├── AppIcon-29x29@1x.png │ │ │ │ ├── AppIcon-29x29@2x-1.png │ │ │ │ ├── AppIcon-29x29@2x.png │ │ │ │ ├── AppIcon-29x29@3x.png │ │ │ │ ├── AppIcon-40x40@1x.png │ │ │ │ ├── AppIcon-40x40@2x-1.png │ │ │ │ ├── AppIcon-40x40@2x.png │ │ │ │ ├── AppIcon-40x40@3x.png │ │ │ │ ├── AppIcon-512@2x.png │ │ │ │ ├── AppIcon-60x60@2x.png │ │ │ │ ├── AppIcon-60x60@3x.png │ │ │ │ ├── AppIcon-76x76@1x.png │ │ │ │ ├── AppIcon-76x76@2x.png │ │ │ │ ├── AppIcon-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ └── Splash.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── splash-2732x2732-1.png │ │ │ │ ├── splash-2732x2732-2.png │ │ │ │ └── splash-2732x2732.png │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── GoogleService-Info.plist │ │ ├── Info.plist │ │ ├── capacitor.config.json │ │ └── config.xml │ │ └── Podfile ├── karma.conf.js ├── package-lock.json ├── package.json ├── src │ ├── app │ │ ├── app-routing.module.ts │ │ ├── app.component.html │ │ ├── app.component.scss │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ └── app.module.ts │ ├── assets │ │ └── .gitkeep │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.scss │ └── test.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.spec.json └── tslint.json ├── ios ├── Plugin.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── Plugin.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Plugin │ ├── Info.plist │ ├── Plugin.h │ ├── Plugin.m │ └── Plugin.swift ├── PluginTests │ ├── Info.plist │ └── PluginTests.swift ├── Podfile └── Podfile.lock ├── package-lock.json ├── package.json ├── rollup.config.js ├── src ├── definitions.ts ├── index.ts └── web.ts └── tsconfig.json /.github/workflows/npmpublish.yml: -------------------------------------------------------------------------------- 1 | name: Node.js Package 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: actions/setup-node@v1 13 | with: 14 | node-version: 16 15 | - run: npm ci 16 | - run: npm test 17 | 18 | publish-npm: 19 | needs: build 20 | runs-on: ubuntu-latest 21 | steps: 22 | - uses: actions/checkout@v2 23 | - uses: actions/setup-node@v1 24 | with: 25 | node-version: 16 26 | registry-url: https://registry.npmjs.org/ 27 | - run: npm ci 28 | - run: npm publish 29 | env: 30 | NODE_AUTH_TOKEN: ${{secrets.NpmToken}} 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | 8 | # dependencies 9 | node_modules/ 10 | hosting.* 11 | 12 | # IDEs and editors 13 | /.idea 14 | .project 15 | .classpath 16 | .c9/ 17 | *.launch 18 | .settings/ 19 | *.sublime-workspace 20 | 21 | # IDE - VSCode 22 | .vscode/* 23 | !.vscode/settings.json 24 | !.vscode/tasks.json 25 | !.vscode/launch.json 26 | !.vscode/extensions.json 27 | 28 | # misc 29 | /.sass-cache 30 | /connect.lock 31 | /coverage 32 | /libpeerconnection.log 33 | npm-debug.log 34 | yarn-error.log 35 | testem.log 36 | /typings 37 | 38 | # System Files 39 | .DS_Store 40 | Thumbs.db 41 | 42 | # capacitor 43 | iOS/build 44 | iOS/Pods 45 | iOS/public 46 | iOS/**/xcuserdata 47 | 48 | # Built application files 49 | /*/build/ 50 | 51 | # Local configuration file (sdk path, etc) 52 | local.properties 53 | 54 | # Gradle generated files 55 | .gradle/ 56 | 57 | # Signing files 58 | .signing/ 59 | 60 | # Android 61 | /android/.idea 62 | /android/android.iml 63 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # node files 2 | dist/ 3 | node_modules/ 4 | 5 | # iOS files 6 | Pods 7 | Build 8 | xcuserdata 9 | 10 | # macOS files 11 | .DS_Store 12 | 13 | 14 | 15 | # Based on Android gitignore template: https://github.com/github/gitignore/blob/master/Android.gitignore 16 | 17 | # Built application files 18 | *.apk 19 | *.ap_ 20 | 21 | # Files for the ART/Dalvik VM 22 | *.dex 23 | 24 | # Java class files 25 | *.class 26 | 27 | # Generated files 28 | bin/ 29 | gen/ 30 | out/ 31 | 32 | # Gradle files 33 | .gradle/ 34 | build/ 35 | 36 | # Local configuration file (sdk path, etc) 37 | local.properties 38 | 39 | # Proguard folder generated by Eclipse 40 | proguard/ 41 | 42 | # Log Files 43 | *.log 44 | 45 | # Android Studio Navigation editor temp files 46 | .navigation/ 47 | 48 | # Android Studio captures folder 49 | captures/ 50 | 51 | # IntelliJ 52 | *.iml 53 | .idea 54 | 55 | # Keystore files 56 | # Uncomment the following line if you do not want to check your keystore files in. 57 | #*.jks 58 | 59 | # External native build folder generated in Android Studio 2.2 and later 60 | .externalNativeBuild 61 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | legacy-peer-deps=true -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | # [3.3.6](https://github.com/CodetrixStudio/CapacitorGoogleAuth/compare/3.3.5...3.3.6) (2023-11-26) 3 | 4 | ## What's Changed 5 | * refactor: deprecate `displayName`, use `name` property (Android) by @itsLucario in https://github.com/CodetrixStudio/CapacitorGoogleAuth/pull/326 6 | * chore: integrate docgen by @reslear in https://github.com/CodetrixStudio/CapacitorGoogleAuth/pull/327 7 | 8 | **Full Changelog**: https://github.com/CodetrixStudio/CapacitorGoogleAuth/compare/3.3.5...3.3.6 9 | 10 | # [3.3.5](https://github.com/CodetrixStudio/CapacitorGoogleAuth/compare/3.3.4...3.3.5) (2023-11-17) 11 | 12 | ## What's Changed 13 | * Update README.md by @Martin-Eckleben in https://github.com/CodetrixStudio/CapacitorGoogleAuth/pull/323 14 | * Bump ios GoogleSignIn to 6.2.4 (Allows requesting scopes during initial signIn) by @Endrzei in https://github.com/CodetrixStudio/CapacitorGoogleAuth/pull/321 15 | 16 | # [3.3.4](https://github.com/CodetrixStudio/CapacitorGoogleAuth/compare/3.3.3...3.3.4) (2023-10-20) 17 | 18 | ## What's Changed 19 | * Android refresh method by @CaolanCode in https://github.com/CodetrixStudio/CapacitorGoogleAuth/pull/314 20 | 21 | # [3.3.3](https://github.com/CodetrixStudio/CapacitorGoogleAuth/compare/3.3.2...3.3.3) (2023-10-09) 22 | 23 | ## What's Changed 24 | * Demo Ionic Angular by @razmans in https://github.com/CodetrixStudio/CapacitorGoogleAuth/pull/290 25 | * Fix #272, #55 by @mirko77 in https://github.com/CodetrixStudio/CapacitorGoogleAuth/pull/288 26 | * Port android test stubs to capacitor 5, and exclude them from npm package by @adamschoenemann in https://github.com/CodetrixStudio/CapacitorGoogleAuth/pull/307 27 | 28 | # [3.3.2](https://github.com/CodetrixStudio/CapacitorGoogleAuth/compare/3.3.1...3.3.2) (2023-06-01) 29 | 30 | ## What's Changed 31 | * Fix peerDependencies for capacitor migration tool by @KerimM in https://github.com/CodetrixStudio/CapacitorGoogleAuth/pull/285 32 | 33 | # [3.3.1](https://github.com/CodetrixStudio/CapacitorGoogleAuth/compare/3.3.0...3.3.1) (2023-05-31) 34 | 35 | ## What's Changed 36 | * fix plugin-migration-v4-to-v5​ by @KerimM in https://github.com/CodetrixStudio/CapacitorGoogleAuth/pull/284 37 | 38 | # [3.3.0](https://github.com/CodetrixStudio/CapacitorGoogleAuth/compare/3.2.2...3.3.0) (2023-05-30) 39 | 40 | ### Features 41 | 42 | - Upgrade to Capacitor 5 [@tponte](https://github.com/tponte) in https://github.com/CodetrixStudio/CapacitorGoogleAuth/pull/277 43 | 44 | # [3.2.2](https://github.com/CodetrixStudio/CapacitorGoogleAuth/compare/3.2.1...3.2.2) (2023-01-27) 45 | 46 | ### Docs 47 | 48 | - Update android plugin instructions by [@teaqu](https://github.com/teaqu) in https://github.com/CodetrixStudio/CapacitorGoogleAuth/pull/254 49 | 50 | # [3.2.1](https://github.com/CodetrixStudio/CapacitorGoogleAuth/v3.2.0...v3.2.1) (2023-01-19) 51 | 52 | ### Fixes 53 | 54 | - sign issue by update google sign dep [#251](https://github.com/CodetrixStudio/CapacitorGoogleAuth/pull/251) ([fc0142a](https://github.com/CodetrixStudio/CapacitorGoogleAuth/commit/fc0142a)) [@riderx](https://github.com/riderx) 55 | 56 | # [3.2.0](https://github.com/CodetrixStudio/CapacitorGoogleAuth/v3.1.3...v3.2.0) (2022-08-15) 57 | 58 | ### Features 59 | 60 | - Support Capacitor 4 [#218](https://github.com/CodetrixStudio/CapacitorGoogleAuth/pull/218) ([0a1f4ff](https://github.com/CodetrixStudio/CapacitorGoogleAuth/commit/0a1f4ff)) - **BREAKING CHANGE!** 61 | 62 | ### Docs 63 | 64 | - Migration guide to capacitor 4 [#221](https://github.com/CodetrixStudio/CapacitorGoogleAuth/pull/221) ([1a79a88](https://github.com/CodetrixStudio/CapacitorGoogleAuth/commit/1a79a88)) 65 | 66 | # [3.1.4](https://github.com/CodetrixStudio/CapacitorGoogleAuth/v3.1.3...v3.1.4) (2022-06-10) 67 | 68 | ### Fixes 69 | 70 | - **Web**: discontinuing authorization support for the Google Sign-In JavaScript Platform Library [#208](https://github.com/CodetrixStudio/CapacitorGoogleAuth/pull/208) ([c9fca36](https://github.com/CodetrixStudio/CapacitorGoogleAuth/commit/c9fca36)), from [#202](https://github.com/CodetrixStudio/CapacitorGoogleAuth/issues/202) 71 | 72 | # [3.1.3](https://github.com/CodetrixStudio/CapacitorGoogleAuth/v3.1.0...v3.1.3) (2022-04-03) 73 | 74 | ### Features 75 | 76 | - iOS: ios return user when restorePreviousSignIn() (#194) ([8b69e12](https://github.com/CodetrixStudio/CapacitorGoogleAuth/commit/8b69e12)), fixes #69 77 | - Android: added accessToken to Android implementation (#173) ([0ed544c](https://github.com/CodetrixStudio/CapacitorGoogleAuth/commit/0ed544c)), closes #53 78 | - Android: separate messages for signin exception (#176) ([96626ba](https://github.com/CodetrixStudio/CapacitorGoogleAuth/commit/96626ba)) 79 | 80 | ### Docs 81 | 82 | - fix initialize parameter keys (#193) ([e7bd54c](https://github.com/CodetrixStudio/CapacitorGoogleAuth/commit/e7bd54c)) 83 | 84 | # [3.1.0](https://github.com/CodetrixStudio/CapacitorGoogleAuth/v3.0.2...v3.1.0) (2021-07-30) 85 | 86 | ### Features 87 | 88 | - supporting .ts and.js config, exported types (#114) ([eaabf9d](https://github.com/CodetrixStudio/CapacitorGoogleAuth/commit/eaabf9d)) 89 | - update ios to GoogleSignIn 6.0.1 Pod (#136) ([4859f9c](https://github.com/CodetrixStudio/CapacitorGoogleAuth/commit/4859f9c)) 90 | - add prettier with ionic config (#137) ([6a7dba5](https://github.com/CodetrixStudio/CapacitorGoogleAuth/commit/6a7dba5)) 91 | - request additional scopes if necessary (#146) ([21f16fd](https://github.com/CodetrixStudio/CapacitorGoogleAuth/commit/21f16fd)) resolves #144 92 | 93 | ### BREAKING CHANGES 94 | 95 | - use `GoogleAuth.initialize()` method instead of `GoogleAuth.init()` 96 | -------------------------------------------------------------------------------- /CodetrixStudioCapacitorGoogleAuth.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | s.name = 'CodetrixStudioCapacitorGoogleAuth' 4 | s.version = '0.0.1' 5 | s.summary = 'Google Auth plugin for capacitor.' 6 | s.license = 'MIT' 7 | s.homepage = 'https://github.com/CodetrixStudio/CapacitorGoogleAuth.git' 8 | s.author = 'CodetrixStudio' 9 | s.source = { :git => 'https://github.com/CodetrixStudio/CapacitorGoogleAuth.git', :tag => s.version.to_s } 10 | s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}' 11 | s.ios.deployment_target = '12.0' 12 | s.dependency 'Capacitor' 13 | s.dependency 'GoogleSignIn', '~> 6.2.4' 14 | s.static_framework = true 15 | end 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Codetrix Studio 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /android/.npmignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2' 3 | androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.6.1' 4 | androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.1.5' 5 | androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.5.1' 6 | gmsPlayServicesAuthVersion = project.hasProperty('gmsPlayServicesAuthVersion') ? rootProject.ext.gmsPlayServicesAuthVersion : '21.2.0' 7 | } 8 | 9 | buildscript { 10 | repositories { 11 | jcenter() 12 | google() 13 | } 14 | dependencies { 15 | classpath 'com.android.tools.build:gradle:8.2.1' 16 | classpath 'com.google.gms:google-services:4.4.0' 17 | } 18 | } 19 | 20 | apply plugin: 'com.android.library' 21 | 22 | android { 23 | namespace "com.codetrixstudio.capacitor.GoogleAuth.capacitorgoogleauth" 24 | compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 34 25 | defaultConfig { 26 | minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22 27 | targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 34 28 | versionCode 1 29 | versionName "1.0" 30 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 31 | } 32 | buildTypes { 33 | release { 34 | minifyEnabled false 35 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 36 | } 37 | } 38 | lintOptions { 39 | abortOnError false 40 | } 41 | compileOptions { 42 | targetCompatibility JavaVersion.VERSION_17 43 | sourceCompatibility JavaVersion.VERSION_17 44 | } 45 | } 46 | 47 | repositories { 48 | google() 49 | jcenter() 50 | mavenCentral() 51 | } 52 | 53 | 54 | dependencies { 55 | implementation fileTree(dir: 'libs', include: ['*.jar']) 56 | implementation project(':capacitor-android') 57 | implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion" 58 | testImplementation "junit:junit:$junitVersion" 59 | androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion" 60 | androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion" 61 | implementation "com.google.android.gms:play-services-auth:$gmsPlayServicesAuthVersion" 62 | } 63 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | 19 | # Supports AndroidX 20 | android.useAndroidX=true -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | # This is normally unused 84 | # shellcheck disable=SC2034 85 | APP_BASE_NAME=${0##*/} 86 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 87 | 88 | # Use the maximum available, or set MAX_FD != -1 to use that value. 89 | MAX_FD=maximum 90 | 91 | warn () { 92 | echo "$*" 93 | } >&2 94 | 95 | die () { 96 | echo 97 | echo "$*" 98 | echo 99 | exit 1 100 | } >&2 101 | 102 | # OS specific support (must be 'true' or 'false'). 103 | cygwin=false 104 | msys=false 105 | darwin=false 106 | nonstop=false 107 | case "$( uname )" in #( 108 | CYGWIN* ) cygwin=true ;; #( 109 | Darwin* ) darwin=true ;; #( 110 | MSYS* | MINGW* ) msys=true ;; #( 111 | NONSTOP* ) nonstop=true ;; 112 | esac 113 | 114 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 115 | 116 | 117 | # Determine the Java command to use to start the JVM. 118 | if [ -n "$JAVA_HOME" ] ; then 119 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 120 | # IBM's JDK on AIX uses strange locations for the executables 121 | JAVACMD=$JAVA_HOME/jre/sh/java 122 | else 123 | JAVACMD=$JAVA_HOME/bin/java 124 | fi 125 | if [ ! -x "$JAVACMD" ] ; then 126 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 127 | 128 | Please set the JAVA_HOME variable in your environment to match the 129 | location of your Java installation." 130 | fi 131 | else 132 | JAVACMD=java 133 | if ! command -v java >/dev/null 2>&1 134 | then 135 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 136 | 137 | Please set the JAVA_HOME variable in your environment to match the 138 | location of your Java installation." 139 | fi 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 147 | # shellcheck disable=SC3045 148 | MAX_FD=$( ulimit -H -n ) || 149 | warn "Could not query maximum file descriptor limit" 150 | esac 151 | case $MAX_FD in #( 152 | '' | soft) :;; #( 153 | *) 154 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 155 | # shellcheck disable=SC3045 156 | ulimit -n "$MAX_FD" || 157 | warn "Could not set maximum file descriptor limit to $MAX_FD" 158 | esac 159 | fi 160 | 161 | # Collect all arguments for the java command, stacking in reverse order: 162 | # * args from the command line 163 | # * the main class name 164 | # * -classpath 165 | # * -D...appname settings 166 | # * --module-path (only if needed) 167 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 168 | 169 | # For Cygwin or MSYS, switch paths to Windows format before running java 170 | if "$cygwin" || "$msys" ; then 171 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 172 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 173 | 174 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 175 | 176 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 177 | for arg do 178 | if 179 | case $arg in #( 180 | -*) false ;; # don't mess with options #( 181 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 182 | [ -e "$t" ] ;; #( 183 | *) false ;; 184 | esac 185 | then 186 | arg=$( cygpath --path --ignore --mixed "$arg" ) 187 | fi 188 | # Roll the args list around exactly as many times as the number of 189 | # args, so each arg winds up back in the position where it started, but 190 | # possibly modified. 191 | # 192 | # NB: a `for` loop captures its iteration list before it begins, so 193 | # changing the positional parameters here affects neither the number of 194 | # iterations, nor the values presented in `arg`. 195 | shift # remove old arg 196 | set -- "$@" "$arg" # push replacement arg 197 | done 198 | fi 199 | 200 | 201 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 202 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 203 | 204 | # Collect all arguments for the java command; 205 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 206 | # shell script including quotes and variable substitutions, so put them in 207 | # double quotes to make sure that they get re-expanded; and 208 | # * put everything else in single quotes, so that it's not re-expanded. 209 | 210 | set -- \ 211 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 212 | -classpath "$CLASSPATH" \ 213 | org.gradle.wrapper.GradleWrapperMain \ 214 | "$@" 215 | 216 | # Stop when "xargs" is not available. 217 | if ! command -v xargs >/dev/null 2>&1 218 | then 219 | die "xargs is not available" 220 | fi 221 | 222 | # Use "xargs" to parse quoted args. 223 | # 224 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 225 | # 226 | # In Bash we could simply go: 227 | # 228 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 229 | # set -- "${ARGS[@]}" "$@" 230 | # 231 | # but POSIX shell has neither arrays nor command substitution, so instead we 232 | # post-process each arg (as a line of input to sed) to backslash-escape any 233 | # character that might be a shell metacharacter, then use eval to reverse 234 | # that process (while maintaining the separation between arguments), and wrap 235 | # the whole thing up as a single "set" statement. 236 | # 237 | # This will of course break if any of these variables contains a newline or 238 | # an unmatched quote. 239 | # 240 | 241 | eval "set -- $( 242 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 243 | xargs -n1 | 244 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 245 | tr '\n' ' ' 246 | )" '"$@"' 247 | 248 | exec "$JAVACMD" "$@" 249 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /android/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':capacitor-android' 2 | project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor') -------------------------------------------------------------------------------- /android/src/androidTest/java/com/getcapacitor/android/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.getcapacitor.android; 2 | 3 | import android.content.Context; 4 | import androidx.test.platform.app.InstrumentationRegistry; 5 | import androidx.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 23 | 24 | assertEquals("com.getcapacitor.android", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /android/src/main/java/com/codetrixstudio/capacitor/GoogleAuth/GoogleAuth.java: -------------------------------------------------------------------------------- 1 | package com.codetrixstudio.capacitor.GoogleAuth; 2 | 3 | import android.accounts.Account; 4 | import android.accounts.AccountManager; 5 | import android.accounts.AccountManagerFuture; 6 | import android.content.Intent; 7 | import android.os.Bundle; 8 | import android.util.Log; 9 | 10 | import androidx.activity.result.ActivityResult; 11 | 12 | import com.codetrixstudio.capacitor.GoogleAuth.capacitorgoogleauth.R; 13 | import com.getcapacitor.JSObject; 14 | import com.getcapacitor.Plugin; 15 | import com.getcapacitor.PluginCall; 16 | import com.getcapacitor.PluginMethod; 17 | import com.getcapacitor.annotation.ActivityCallback; 18 | import com.getcapacitor.annotation.CapacitorPlugin; 19 | import com.google.android.gms.auth.api.signin.GoogleSignIn; 20 | import com.google.android.gms.auth.api.signin.GoogleSignInAccount; 21 | import com.google.android.gms.auth.api.signin.GoogleSignInClient; 22 | import com.google.android.gms.auth.api.signin.GoogleSignInOptions; 23 | import com.google.android.gms.common.api.ApiException; 24 | import com.google.android.gms.common.api.Scope; 25 | import com.google.android.gms.tasks.Task; 26 | 27 | import org.json.JSONException; 28 | import org.json.JSONObject; 29 | 30 | import java.io.BufferedInputStream; 31 | import java.io.BufferedReader; 32 | import java.io.IOException; 33 | import java.io.InputStream; 34 | import java.io.InputStreamReader; 35 | import java.net.HttpURLConnection; 36 | import java.net.URL; 37 | import java.util.concurrent.ExecutorService; 38 | import java.util.concurrent.Executors; 39 | import com.google.android.gms.tasks.OnSuccessListener; 40 | import com.google.android.gms.tasks.OnFailureListener; 41 | 42 | @CapacitorPlugin() 43 | public class GoogleAuth extends Plugin { 44 | private final static String VERIFY_TOKEN_URL = "https://www.googleapis.com/oauth2/v1/tokeninfo?access_token="; 45 | private final static String FIELD_TOKEN_EXPIRES_IN = "expires_in"; 46 | private final static String FIELD_ACCESS_TOKEN = "accessToken"; 47 | private final static String FIELD_TOKEN_EXPIRES = "expires"; 48 | 49 | // see https://developers.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInStatusCodes#SIGN_IN_CANCELLED 50 | private final static int SIGN_IN_CANCELLED = 12501; 51 | 52 | public static final int KAssumeStaleTokenSec = 60; 53 | 54 | private GoogleSignInClient googleSignInClient; 55 | 56 | public void loadSignInClient (String clientId, boolean forceCodeForRefreshToken, String[] scopeArray) { 57 | GoogleSignInOptions.Builder googleSignInBuilder = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 58 | .requestIdToken(clientId) 59 | .requestEmail(); 60 | 61 | if (forceCodeForRefreshToken) { 62 | googleSignInBuilder.requestServerAuthCode(clientId, true); 63 | } 64 | 65 | Scope[] scopes = new Scope[scopeArray.length - 1]; 66 | Scope firstScope = new Scope(scopeArray[0]); 67 | for (int i = 1; i < scopeArray.length; i++) { 68 | scopes[i - 1] = new Scope(scopeArray[i]); 69 | } 70 | googleSignInBuilder.requestScopes(firstScope, scopes); 71 | 72 | GoogleSignInOptions googleSignInOptions = googleSignInBuilder.build(); 73 | googleSignInClient = GoogleSignIn.getClient(this.getContext(), googleSignInOptions); 74 | } 75 | 76 | @Override 77 | public void load() {} 78 | 79 | @PluginMethod() 80 | public void signIn(PluginCall call) { 81 | if(googleSignInClient == null){ 82 | rejectWithNullClientError(call); 83 | return; 84 | } 85 | Intent signInIntent = googleSignInClient.getSignInIntent(); 86 | startActivityForResult(call, signInIntent, "signInResult"); 87 | } 88 | 89 | @ActivityCallback 90 | protected void signInResult(PluginCall call, ActivityResult result) { 91 | if (call == null) return; 92 | 93 | Task completedTask = GoogleSignIn.getSignedInAccountFromIntent(result.getData()); 94 | 95 | try { 96 | GoogleSignInAccount account = completedTask.getResult(ApiException.class); 97 | 98 | // The accessToken is retrieved by executing a network request against the Google API, so it needs to run in a thread 99 | ExecutorService executor = Executors.newSingleThreadExecutor(); 100 | executor.execute(() -> { 101 | try { 102 | JSONObject accessTokenObject = getAuthToken(account.getAccount(), true); 103 | 104 | JSObject authentication = new JSObject(); 105 | authentication.put("idToken", account.getIdToken()); 106 | authentication.put(FIELD_ACCESS_TOKEN, accessTokenObject.get(FIELD_ACCESS_TOKEN)); 107 | authentication.put(FIELD_TOKEN_EXPIRES, accessTokenObject.get(FIELD_TOKEN_EXPIRES)); 108 | authentication.put(FIELD_TOKEN_EXPIRES_IN, accessTokenObject.get(FIELD_TOKEN_EXPIRES_IN)); 109 | 110 | JSObject user = new JSObject(); 111 | user.put("serverAuthCode", account.getServerAuthCode()); 112 | user.put("idToken", account.getIdToken()); 113 | user.put("authentication", authentication); 114 | 115 | user.put("name", account.getDisplayName()); 116 | // Deprecated: Use `user` instead of `displayName` 117 | user.put("displayName", account.getDisplayName()); 118 | user.put("email", account.getEmail()); 119 | user.put("familyName", account.getFamilyName()); 120 | user.put("givenName", account.getGivenName()); 121 | user.put("id", account.getId()); 122 | user.put("imageUrl", account.getPhotoUrl()); 123 | 124 | call.resolve(user); 125 | } catch (Exception e) { 126 | e.printStackTrace(); 127 | call.reject("Something went wrong while retrieving access token", e); 128 | } 129 | }); 130 | } catch (ApiException e) { 131 | if (SIGN_IN_CANCELLED == e.getStatusCode()) { 132 | call.reject("The user canceled the sign-in flow.", "" + e.getStatusCode()); 133 | } else { 134 | call.reject("Something went wrong", "" + e.getStatusCode()); 135 | } 136 | } 137 | } 138 | 139 | @PluginMethod() 140 | public void refresh(final PluginCall call) { 141 | GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(getContext()); 142 | if (account == null) { 143 | call.reject("User not logged in."); 144 | } else { 145 | try { 146 | JSONObject accessTokenObject = getAuthToken(account.getAccount(), true); 147 | 148 | JSObject authentication = new JSObject(); 149 | authentication.put("idToken", account.getIdToken()); 150 | authentication.put(FIELD_ACCESS_TOKEN, accessTokenObject.get(FIELD_ACCESS_TOKEN)); 151 | authentication.put("refreshToken", ""); 152 | call.resolve(authentication); 153 | } catch(Exception e){ 154 | e.printStackTrace(); 155 | call.reject("Something went wrong while retrieving access token", e); 156 | } 157 | } 158 | } 159 | 160 | @PluginMethod() 161 | public void signOut(final PluginCall call) { 162 | if(googleSignInClient == null){ 163 | rejectWithNullClientError(call); 164 | return; 165 | } 166 | googleSignInClient.signOut() 167 | .addOnSuccessListener(getActivity(), new OnSuccessListener() { 168 | @Override 169 | public void onSuccess(Void aVoid) { 170 | call.resolve(); 171 | } 172 | }) 173 | .addOnFailureListener(getActivity(), new OnFailureListener() { 174 | @Override 175 | public void onFailure(Exception e) { 176 | call.reject("Sign out failed", e); 177 | } 178 | }); 179 | } 180 | 181 | @PluginMethod() 182 | public void initialize(final PluginCall call) { 183 | // get data from config 184 | String configClientId = getConfig().getString("androidClientId", 185 | getConfig().getString("clientId", 186 | this.getContext().getString(R.string.server_client_id))); 187 | boolean configForceCodeForRefreshToken = getConfig().getBoolean("forceCodeForRefreshToken", false); 188 | // need to get this as string so as to standardize with data from plugin call 189 | String configScopeArray = getConfig().getString("scopes", new String()); 190 | 191 | // get client id from plugin call, fallback to be client id from config 192 | String clientId = call.getData().getString("clientId", configClientId); 193 | // get forceCodeForRefreshToken from call, fallback to be from config 194 | boolean forceCodeForRefreshToken = call.getData().getBoolean("grantOfflineAccess", configForceCodeForRefreshToken); 195 | // get scopes from call, fallback to be from config 196 | String scopesStr = call.getData().getString("scopes", configScopeArray); 197 | // replace all the symbols from parsing array as string 198 | // leaving only scopes delimited by commas 199 | String replacedScopesStr = scopesStr 200 | .replaceAll("[\"\\[\\] ]", "") 201 | // this is for scopes that are in the form of a url 202 | .replace("\\", ""); 203 | 204 | // scope to be in the form of an array 205 | String[] scopeArray = replacedScopesStr.split(","); 206 | 207 | loadSignInClient(clientId, forceCodeForRefreshToken, scopeArray); 208 | call.resolve(); 209 | } 210 | 211 | // Logic to retrieve accessToken, see https://github.com/EddyVerbruggen/cordova-plugin-googleplus/blob/master/src/android/GooglePlus.java 212 | private JSONObject getAuthToken(Account account, boolean retry) throws Exception { 213 | AccountManager manager = AccountManager.get(getContext()); 214 | AccountManagerFuture future = manager.getAuthToken(account, "oauth2:profile email", null, false, null, null); 215 | Bundle bundle = future.getResult(); 216 | String authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN); 217 | try { 218 | return verifyToken(authToken); 219 | } catch (IOException e) { 220 | if (retry) { 221 | manager.invalidateAuthToken("com.google", authToken); 222 | return getAuthToken(account, false); 223 | } else { 224 | throw e; 225 | } 226 | } 227 | } 228 | 229 | private JSONObject verifyToken(String authToken) throws IOException, JSONException { 230 | URL url = new URL(VERIFY_TOKEN_URL + authToken); 231 | HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 232 | urlConnection.setInstanceFollowRedirects(true); 233 | String stringResponse = fromStream(new BufferedInputStream(urlConnection.getInputStream())); 234 | /* expecting: 235 | { 236 | "issued_to": "xxxxxx-xxxxxxxxxxxxxxx.apps.googleusercontent.com", 237 | "audience": "xxxxxx-xxxxxxxxxxxxxxxx.apps.googleusercontent.com", 238 | "user_id": "xxxxxxxxxxxxxxxxxxxx", 239 | "scope": "https://www.googleapis.com/auth/userinfo.email openid https://www.googleapis.com/auth/userinfo.profile", 240 | "expires_in": 3220, 241 | "email": "xxxxxxx@xxxxx.com", 242 | "verified_email": true, 243 | "access_type": "online" 244 | } 245 | */ 246 | 247 | Log.d("AuthenticatedBackend", "token: " + authToken + ", verification: " + stringResponse); 248 | JSONObject jsonResponse = new JSONObject(stringResponse); 249 | int expires_in = jsonResponse.getInt(FIELD_TOKEN_EXPIRES_IN); 250 | if (expires_in < KAssumeStaleTokenSec) { 251 | throw new IOException("Auth token soon expiring."); 252 | } 253 | jsonResponse.put(FIELD_ACCESS_TOKEN, authToken); 254 | jsonResponse.put(FIELD_TOKEN_EXPIRES, expires_in + (System.currentTimeMillis() / 1000)); 255 | return jsonResponse; 256 | } 257 | 258 | private static String fromStream(InputStream is) throws IOException { 259 | BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 260 | StringBuilder sb = new StringBuilder(); 261 | String line; 262 | while ((line = reader.readLine()) != null) { 263 | sb.append(line).append("\n"); 264 | } 265 | reader.close(); 266 | return sb.toString(); 267 | } 268 | 269 | private void rejectWithNullClientError(final PluginCall call) { 270 | call.reject("Google services are not ready. Please call initialize() first"); 271 | } 272 | } 273 | -------------------------------------------------------------------------------- /android/src/main/res/layout/bridge_layout_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /android/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /android/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Your Web Client Key 3 | 4 | -------------------------------------------------------------------------------- /android/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /android/src/test/java/com/getcapacitor/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.getcapacitor; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /demo-ionic-angular/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | Chrome >=79 12 | ChromeAndroid >=79 13 | Firefox >=70 14 | Edge >=79 15 | Safari >=14 16 | iOS >=14 17 | -------------------------------------------------------------------------------- /demo-ionic-angular/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /demo-ionic-angular/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "ignorePatterns": ["projects/**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts"], 7 | "parserOptions": { 8 | "project": ["tsconfig.json"], 9 | "createDefaultProgram": true 10 | }, 11 | "extends": [ 12 | "plugin:@angular-eslint/recommended", 13 | "plugin:@angular-eslint/template/process-inline-templates" 14 | ], 15 | "rules": { 16 | "@angular-eslint/component-class-suffix": [ 17 | "error", 18 | { 19 | "suffixes": ["Page", "Component"] 20 | } 21 | ], 22 | "@angular-eslint/component-selector": [ 23 | "error", 24 | { 25 | "type": "element", 26 | "prefix": "app", 27 | "style": "kebab-case" 28 | } 29 | ], 30 | "@angular-eslint/directive-selector": [ 31 | "error", 32 | { 33 | "type": "attribute", 34 | "prefix": "app", 35 | "style": "camelCase" 36 | } 37 | ] 38 | } 39 | }, 40 | { 41 | "files": ["*.html"], 42 | "extends": ["plugin:@angular-eslint/template/recommended"], 43 | "rules": {} 44 | } 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /demo-ionic-angular/.gitignore: -------------------------------------------------------------------------------- 1 | # Specifies intentionally untracked files to ignore when using Git 2 | # http://git-scm.com/docs/gitignore 3 | 4 | *~ 5 | *.sw[mnpcod] 6 | .tmp 7 | *.tmp 8 | *.tmp.* 9 | UserInterfaceState.xcuserstate 10 | $RECYCLE.BIN/ 11 | 12 | *.log 13 | log.txt 14 | 15 | 16 | /.sourcemaps 17 | /.versions 18 | /coverage 19 | 20 | # Ionic 21 | /.ionic 22 | /www 23 | /platforms 24 | /plugins 25 | 26 | # Compiled output 27 | /dist 28 | /tmp 29 | /out-tsc 30 | /bazel-out 31 | 32 | # Node 33 | /node_modules 34 | npm-debug.log 35 | yarn-error.log 36 | 37 | # IDEs and editors 38 | .idea/ 39 | .project 40 | .classpath 41 | .c9/ 42 | *.launch 43 | .settings/ 44 | *.sublime-project 45 | *.sublime-workspace 46 | 47 | # Visual Studio Code 48 | .vscode/* 49 | !.vscode/settings.json 50 | !.vscode/tasks.json 51 | !.vscode/launch.json 52 | !.vscode/extensions.json 53 | .history/* 54 | 55 | 56 | # Miscellaneous 57 | /.angular 58 | /.angular/cache 59 | .sass-cache/ 60 | /connect.lock 61 | /coverage 62 | /libpeerconnection.log 63 | testem.log 64 | /typings 65 | 66 | # System files 67 | .DS_Store 68 | Thumbs.db 69 | -------------------------------------------------------------------------------- /demo-ionic-angular/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "ionic.ionic" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /demo-ionic-angular/README.md: -------------------------------------------------------------------------------- 1 | # Demo with Ionic Angular version 7 2 | 3 | To test out this demo on an Ionic app, you will need to make sure that you have installed the latest version of Ionic: 4 | 5 | 1. `npm install -g @ionic/cli` 6 | 7 | To serve this, it is recommended to use port 4200, please use this command: 8 | 9 | 2. `ionic serve -p 4200` 10 | 11 | The credentials should be logged out after pressing the sign in button and the sign in process is completed. 12 | 13 | Thank you and have a nice day. -------------------------------------------------------------------------------- /demo-ionic-angular/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "app": { 7 | "projectType": "application", 8 | "schematics": {}, 9 | "root": "", 10 | "sourceRoot": "src", 11 | "prefix": "app", 12 | "architect": { 13 | "build": { 14 | "builder": "@angular-devkit/build-angular:browser", 15 | "options": { 16 | "outputPath": "www", 17 | "index": "src/index.html", 18 | "main": "src/main.ts", 19 | "polyfills": "src/polyfills.ts", 20 | "tsConfig": "tsconfig.app.json", 21 | "inlineStyleLanguage": "scss", 22 | "assets": [ 23 | { 24 | "glob": "**/*", 25 | "input": "src/assets", 26 | "output": "assets" 27 | }, 28 | { 29 | "glob": "**/*.svg", 30 | "input": "node_modules/ionicons/dist/ionicons/svg", 31 | "output": "./svg" 32 | } 33 | ], 34 | "styles": ["src/theme/variables.scss", "src/global.scss"], 35 | "scripts": [] 36 | }, 37 | "configurations": { 38 | "production": { 39 | "budgets": [ 40 | { 41 | "type": "initial", 42 | "maximumWarning": "2mb", 43 | "maximumError": "5mb" 44 | }, 45 | { 46 | "type": "anyComponentStyle", 47 | "maximumWarning": "2kb", 48 | "maximumError": "4kb" 49 | } 50 | ], 51 | "fileReplacements": [ 52 | { 53 | "replace": "src/environments/environment.ts", 54 | "with": "src/environments/environment.prod.ts" 55 | } 56 | ], 57 | "outputHashing": "all" 58 | }, 59 | "development": { 60 | "buildOptimizer": false, 61 | "optimization": false, 62 | "vendorChunk": true, 63 | "extractLicenses": false, 64 | "sourceMap": true, 65 | "namedChunks": true 66 | }, 67 | "ci": { 68 | "progress": false 69 | } 70 | }, 71 | "defaultConfiguration": "production" 72 | }, 73 | "serve": { 74 | "builder": "@angular-devkit/build-angular:dev-server", 75 | "configurations": { 76 | "production": { 77 | "browserTarget": "app:build:production" 78 | }, 79 | "development": { 80 | "browserTarget": "app:build:development" 81 | }, 82 | "ci": { 83 | "progress": false 84 | } 85 | }, 86 | "defaultConfiguration": "development" 87 | }, 88 | "extract-i18n": { 89 | "builder": "@angular-devkit/build-angular:extract-i18n", 90 | "options": { 91 | "browserTarget": "app:build" 92 | } 93 | }, 94 | "test": { 95 | "builder": "@angular-devkit/build-angular:karma", 96 | "options": { 97 | "main": "src/test.ts", 98 | "polyfills": "src/polyfills.ts", 99 | "tsConfig": "tsconfig.spec.json", 100 | "karmaConfig": "karma.conf.js", 101 | "inlineStyleLanguage": "scss", 102 | "assets": [ 103 | { 104 | "glob": "**/*", 105 | "input": "src/assets", 106 | "output": "assets" 107 | }, 108 | { 109 | "glob": "**/*.svg", 110 | "input": "node_modules/ionicons/dist/ionicons/svg", 111 | "output": "./svg" 112 | } 113 | ], 114 | "styles": ["src/theme/variables.scss", "src/global.scss"], 115 | "scripts": [] 116 | }, 117 | "configurations": { 118 | "ci": { 119 | "progress": false, 120 | "watch": false 121 | } 122 | } 123 | }, 124 | "lint": { 125 | "builder": "@angular-eslint/builder:lint", 126 | "options": { 127 | "lintFilePatterns": [ 128 | "src/**/*.ts", 129 | "src/**/*.html" 130 | ] 131 | } 132 | } 133 | } 134 | } 135 | }, 136 | "cli": { 137 | "schematicCollections": [ 138 | "@ionic/angular-toolkit" 139 | ], 140 | "analytics": false 141 | }, 142 | "schematics": { 143 | "@ionic/angular-toolkit:component": { 144 | "styleext": "scss" 145 | }, 146 | "@ionic/angular-toolkit:page": { 147 | "styleext": "scss" 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /demo-ionic-angular/capacitor.config.ts: -------------------------------------------------------------------------------- 1 | import { CapacitorConfig } from '@capacitor/cli'; 2 | 3 | const config: CapacitorConfig = { 4 | appId: 'io.ionic.starter', 5 | appName: 'demo-ionic-angular', 6 | webDir: 'www', 7 | server: { 8 | androidScheme: 'https' 9 | } 10 | }; 11 | 12 | export default config; 13 | -------------------------------------------------------------------------------- /demo-ionic-angular/ionic.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-ionic-angular", 3 | "integrations": { 4 | "capacitor": {} 5 | }, 6 | "type": "angular" 7 | } 8 | -------------------------------------------------------------------------------- /demo-ionic-angular/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | jasmine: { 17 | // you can add configuration options for Jasmine here 18 | // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html 19 | // for example, you can disable the random execution with `random: false` 20 | // or set a specific seed with `seed: 4321` 21 | }, 22 | clearContext: false // leave Jasmine Spec Runner output visible in browser 23 | }, 24 | jasmineHtmlReporter: { 25 | suppressAll: true // removes the duplicated traces 26 | }, 27 | coverageReporter: { 28 | dir: require('path').join(__dirname, './coverage/app'), 29 | subdir: '.', 30 | reporters: [ 31 | { type: 'html' }, 32 | { type: 'text-summary' } 33 | ] 34 | }, 35 | reporters: ['progress', 'kjhtml'], 36 | port: 9876, 37 | colors: true, 38 | logLevel: config.LOG_INFO, 39 | autoWatch: true, 40 | browsers: ['Chrome'], 41 | singleRun: false, 42 | restartOnFileChange: true 43 | }); 44 | }; 45 | -------------------------------------------------------------------------------- /demo-ionic-angular/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-ionic-angular", 3 | "version": "0.0.1", 4 | "author": "Ionic Framework", 5 | "homepage": "https://ionicframework.com/", 6 | "scripts": { 7 | "ng": "ng", 8 | "start": "ng serve", 9 | "build": "ng build", 10 | "watch": "ng build --watch --configuration development", 11 | "test": "ng test", 12 | "lint": "ng lint" 13 | }, 14 | "private": true, 15 | "dependencies": { 16 | "@angular/animations": "^16.0.0", 17 | "@angular/common": "^16.0.0", 18 | "@angular/compiler": "^16.0.0", 19 | "@angular/core": "^16.0.0", 20 | "@angular/forms": "^16.0.0", 21 | "@angular/platform-browser": "^16.0.0", 22 | "@angular/platform-browser-dynamic": "^16.0.0", 23 | "@angular/router": "^16.0.0", 24 | "@capacitor/app": "^5.0.5", 25 | "@capacitor/core": "5.1.1", 26 | "@capacitor/haptics": "^5.0.5", 27 | "@capacitor/ios": "^5.1.1", 28 | "@capacitor/keyboard": "^5.0.5", 29 | "@capacitor/status-bar": "^5.0.5", 30 | "@codetrix-studio/capacitor-google-auth": "^3.3.2", 31 | "@ionic/angular": "^7.0.0", 32 | "ionicons": "^7.0.0", 33 | "rxjs": "~7.8.0", 34 | "tslib": "^2.3.0", 35 | "zone.js": "~0.13.0" 36 | }, 37 | "devDependencies": { 38 | "@angular-devkit/build-angular": "^16.0.0", 39 | "@angular-eslint/builder": "^16.0.0", 40 | "@angular-eslint/eslint-plugin": "^16.0.0", 41 | "@angular-eslint/eslint-plugin-template": "^16.0.0", 42 | "@angular-eslint/schematics": "^16.0.0", 43 | "@angular-eslint/template-parser": "^16.0.0", 44 | "@angular/cli": "^16.0.0", 45 | "@angular/compiler": "^16.0.0", 46 | "@angular/compiler-cli": "^16.0.0", 47 | "@angular/language-service": "^16.0.0", 48 | "@capacitor/cli": "5.1.1", 49 | "@ionic/angular-toolkit": "^9.0.0", 50 | "@types/jasmine": "~4.3.0", 51 | "@types/node": "^12.11.1", 52 | "@typescript-eslint/eslint-plugin": "5.3.0", 53 | "@typescript-eslint/parser": "5.3.0", 54 | "eslint": "^7.26.0", 55 | "eslint-plugin-import": "2.22.1", 56 | "eslint-plugin-jsdoc": "30.7.6", 57 | "eslint-plugin-prefer-arrow": "1.2.2", 58 | "jasmine-core": "~4.6.0", 59 | "jasmine-spec-reporter": "~5.0.0", 60 | "karma": "~6.4.0", 61 | "karma-chrome-launcher": "~3.2.0", 62 | "karma-coverage": "~2.2.0", 63 | "karma-coverage-istanbul-reporter": "~3.0.2", 64 | "karma-jasmine": "~5.1.0", 65 | "karma-jasmine-html-reporter": "~2.0.0", 66 | "ts-node": "^8.3.0", 67 | "typescript": "~5.0.2" 68 | }, 69 | "description": "An Ionic project" 70 | } 71 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { PreloadAllModules, RouterModule, Routes } from '@angular/router'; 3 | 4 | const routes: Routes = [ 5 | { 6 | path: 'home', 7 | loadChildren: () => import('./home/home.module').then( m => m.HomePageModule) 8 | }, 9 | { 10 | path: '', 11 | redirectTo: 'home', 12 | pathMatch: 'full' 13 | }, 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [ 18 | RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }) 19 | ], 20 | exports: [RouterModule] 21 | }) 22 | export class AppRoutingModule { } 23 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/app/app.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo-ionic-angular/src/app/app.component.scss -------------------------------------------------------------------------------- /demo-ionic-angular/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; 2 | import { TestBed } from '@angular/core/testing'; 3 | 4 | import { AppComponent } from './app.component'; 5 | 6 | describe('AppComponent', () => { 7 | 8 | beforeEach(async () => { 9 | await TestBed.configureTestingModule({ 10 | declarations: [AppComponent], 11 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 12 | }).compileComponents(); 13 | }); 14 | 15 | it('should create the app', () => { 16 | const fixture = TestBed.createComponent(AppComponent); 17 | const app = fixture.componentInstance; 18 | expect(app).toBeTruthy(); 19 | }); 20 | 21 | }); 22 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { GoogleAuth } from '@codetrix-studio/capacitor-google-auth'; 3 | import { Platform } from '@ionic/angular'; 4 | import { environment } from 'src/environments/environment'; 5 | 6 | @Component({ 7 | selector: 'app-root', 8 | templateUrl: 'app.component.html', 9 | styleUrls: ['app.component.scss'], 10 | }) 11 | export class AppComponent { 12 | constructor( 13 | private platform: Platform, 14 | ) { 15 | this.initializeApp(); 16 | } 17 | 18 | initializeApp() { 19 | this.platform.ready().then(() => { 20 | console.log('READY!') 21 | GoogleAuth.initialize( 22 | { 23 | clientId:environment.clientID, 24 | scopes: ['profile', 'email'], 25 | grantOfflineAccess: true, 26 | } 27 | ) 28 | }) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { RouteReuseStrategy } from '@angular/router'; 4 | 5 | import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; 6 | 7 | import { AppComponent } from './app.component'; 8 | import { AppRoutingModule } from './app-routing.module'; 9 | 10 | @NgModule({ 11 | declarations: [AppComponent], 12 | imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule], 13 | providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }], 14 | bootstrap: [AppComponent], 15 | }) 16 | export class AppModule {} 17 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/app/home/home-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | import { HomePage } from './home.page'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: '', 8 | component: HomePage, 9 | } 10 | ]; 11 | 12 | @NgModule({ 13 | imports: [RouterModule.forChild(routes)], 14 | exports: [RouterModule] 15 | }) 16 | export class HomePageRoutingModule {} 17 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/app/home/home.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { IonicModule } from '@ionic/angular'; 4 | import { FormsModule } from '@angular/forms'; 5 | import { HomePage } from './home.page'; 6 | 7 | import { HomePageRoutingModule } from './home-routing.module'; 8 | 9 | 10 | @NgModule({ 11 | imports: [ 12 | CommonModule, 13 | FormsModule, 14 | IonicModule, 15 | HomePageRoutingModule 16 | ], 17 | declarations: [HomePage] 18 | }) 19 | export class HomePageModule {} 20 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/app/home/home.page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Capacitor Google Auth App 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Sign In with Google Auth 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | Sign Out with Google Auth 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/app/home/home.page.scss: -------------------------------------------------------------------------------- 1 | #container { 2 | text-align: center; 3 | 4 | position: absolute; 5 | left: 0; 6 | right: 0; 7 | top: 50%; 8 | transform: translateY(-50%); 9 | } 10 | 11 | #container strong { 12 | font-size: 20px; 13 | line-height: 26px; 14 | } 15 | 16 | #container p { 17 | font-size: 16px; 18 | line-height: 22px; 19 | 20 | color: #8c8c8c; 21 | 22 | margin: 0; 23 | } 24 | 25 | #container a { 26 | text-decoration: none; 27 | } -------------------------------------------------------------------------------- /demo-ionic-angular/src/app/home/home.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { IonicModule } from '@ionic/angular'; 3 | 4 | import { HomePage } from './home.page'; 5 | 6 | describe('HomePage', () => { 7 | let component: HomePage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(async () => { 11 | await TestBed.configureTestingModule({ 12 | declarations: [HomePage], 13 | imports: [IonicModule.forRoot()] 14 | }).compileComponents(); 15 | 16 | fixture = TestBed.createComponent(HomePage); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/app/home/home.page.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { GoogleAuth } from '@codetrix-studio/capacitor-google-auth'; 3 | 4 | @Component({ 5 | selector: 'app-home', 6 | templateUrl: 'home.page.html', 7 | styleUrls: ['home.page.scss'], 8 | }) 9 | export class HomePage { 10 | 11 | constructor() {} 12 | 13 | public async signIn(){ 14 | let googleUser = await GoogleAuth.signIn(); 15 | console.log(googleUser); 16 | } 17 | 18 | public signOut(){ 19 | GoogleAuth.signOut(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/assets/icon/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo-ionic-angular/src/assets/icon/favicon.png -------------------------------------------------------------------------------- /demo-ionic-angular/src/assets/shapes.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | clientID:'' 4 | }; 5 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false, 7 | clientID:'744254868856-6j8dflcgq0tiqt0b506b61etukcq3rdm.apps.googleusercontent.com' 8 | }; 9 | 10 | /* 11 | * For easier debugging in development mode, you can import the following file 12 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 13 | * 14 | * This import should be commented out in production mode because it will have a negative impact 15 | * on performance if an error is thrown. 16 | */ 17 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI. 18 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/global.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * App Global CSS 3 | * ---------------------------------------------------------------------------- 4 | * Put style rules here that you want to apply globally. These styles are for 5 | * the entire app and not just one component. Additionally, this file can be 6 | * used as an entry point to import other CSS/Sass files to be included in the 7 | * output CSS. 8 | * For more information on global stylesheets, visit the documentation: 9 | * https://ionicframework.com/docs/layout/global-stylesheets 10 | */ 11 | 12 | /* Core CSS required for Ionic components to work properly */ 13 | @import "@ionic/angular/css/core.css"; 14 | 15 | /* Basic CSS for apps built with Ionic */ 16 | @import "@ionic/angular/css/normalize.css"; 17 | @import "@ionic/angular/css/structure.css"; 18 | @import "@ionic/angular/css/typography.css"; 19 | @import '@ionic/angular/css/display.css'; 20 | 21 | /* Optional CSS utils that can be commented out */ 22 | @import "@ionic/angular/css/padding.css"; 23 | @import "@ionic/angular/css/float-elements.css"; 24 | @import "@ionic/angular/css/text-alignment.css"; 25 | @import "@ionic/angular/css/text-transformation.css"; 26 | @import "@ionic/angular/css/flex-utils.css"; 27 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Ionic App 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.log(err)); 13 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes recent versions of Safari, Chrome (including 12 | * Opera), Edge on the desktop, and iOS and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** 22 | * By default, zone.js will patch all possible macroTask and DomEvents 23 | * user can disable parts of macroTask/DomEvents patch by setting following flags 24 | * because those flags need to be set before `zone.js` being loaded, and webpack 25 | * will put import in the top of bundle, so user need to create a separate file 26 | * in this directory (for example: zone-flags.ts), and put the following flags 27 | * into that file, and then add the following code before importing zone.js. 28 | * import './zone-flags'; 29 | * 30 | * The flags allowed in zone-flags.ts are listed here. 31 | * 32 | * The following flags will work for all browsers. 33 | * 34 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 35 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 36 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 37 | * 38 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 39 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 40 | * 41 | * (window as any).__Zone_enable_cross_context_check = true; 42 | * 43 | */ 44 | 45 | import './zone-flags'; 46 | 47 | /*************************************************************************************************** 48 | * Zone JS is required by default for Angular itself. 49 | */ 50 | import 'zone.js'; // Included with Angular CLI. 51 | 52 | 53 | /*************************************************************************************************** 54 | * APPLICATION IMPORTS 55 | */ 56 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | // First, initialize the Angular testing environment. 11 | getTestBed().initTestEnvironment( 12 | BrowserDynamicTestingModule, 13 | platformBrowserDynamicTesting(), 14 | ); 15 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/theme/variables.scss: -------------------------------------------------------------------------------- 1 | // Ionic Variables and Theming. For more info, please see: 2 | // http://ionicframework.com/docs/theming/ 3 | 4 | /** Ionic CSS Variables **/ 5 | :root { 6 | /** primary **/ 7 | --ion-color-primary: #3880ff; 8 | --ion-color-primary-rgb: 56, 128, 255; 9 | --ion-color-primary-contrast: #ffffff; 10 | --ion-color-primary-contrast-rgb: 255, 255, 255; 11 | --ion-color-primary-shade: #3171e0; 12 | --ion-color-primary-tint: #4c8dff; 13 | 14 | /** secondary **/ 15 | --ion-color-secondary: #3dc2ff; 16 | --ion-color-secondary-rgb: 61, 194, 255; 17 | --ion-color-secondary-contrast: #ffffff; 18 | --ion-color-secondary-contrast-rgb: 255, 255, 255; 19 | --ion-color-secondary-shade: #36abe0; 20 | --ion-color-secondary-tint: #50c8ff; 21 | 22 | /** tertiary **/ 23 | --ion-color-tertiary: #5260ff; 24 | --ion-color-tertiary-rgb: 82, 96, 255; 25 | --ion-color-tertiary-contrast: #ffffff; 26 | --ion-color-tertiary-contrast-rgb: 255, 255, 255; 27 | --ion-color-tertiary-shade: #4854e0; 28 | --ion-color-tertiary-tint: #6370ff; 29 | 30 | /** success **/ 31 | --ion-color-success: #2dd36f; 32 | --ion-color-success-rgb: 45, 211, 111; 33 | --ion-color-success-contrast: #ffffff; 34 | --ion-color-success-contrast-rgb: 255, 255, 255; 35 | --ion-color-success-shade: #28ba62; 36 | --ion-color-success-tint: #42d77d; 37 | 38 | /** warning **/ 39 | --ion-color-warning: #ffc409; 40 | --ion-color-warning-rgb: 255, 196, 9; 41 | --ion-color-warning-contrast: #000000; 42 | --ion-color-warning-contrast-rgb: 0, 0, 0; 43 | --ion-color-warning-shade: #e0ac08; 44 | --ion-color-warning-tint: #ffca22; 45 | 46 | /** danger **/ 47 | --ion-color-danger: #eb445a; 48 | --ion-color-danger-rgb: 235, 68, 90; 49 | --ion-color-danger-contrast: #ffffff; 50 | --ion-color-danger-contrast-rgb: 255, 255, 255; 51 | --ion-color-danger-shade: #cf3c4f; 52 | --ion-color-danger-tint: #ed576b; 53 | 54 | /** dark **/ 55 | --ion-color-dark: #222428; 56 | --ion-color-dark-rgb: 34, 36, 40; 57 | --ion-color-dark-contrast: #ffffff; 58 | --ion-color-dark-contrast-rgb: 255, 255, 255; 59 | --ion-color-dark-shade: #1e2023; 60 | --ion-color-dark-tint: #383a3e; 61 | 62 | /** medium **/ 63 | --ion-color-medium: #92949c; 64 | --ion-color-medium-rgb: 146, 148, 156; 65 | --ion-color-medium-contrast: #ffffff; 66 | --ion-color-medium-contrast-rgb: 255, 255, 255; 67 | --ion-color-medium-shade: #808289; 68 | --ion-color-medium-tint: #9d9fa6; 69 | 70 | /** light **/ 71 | --ion-color-light: #f4f5f8; 72 | --ion-color-light-rgb: 244, 245, 248; 73 | --ion-color-light-contrast: #000000; 74 | --ion-color-light-contrast-rgb: 0, 0, 0; 75 | --ion-color-light-shade: #d7d8da; 76 | --ion-color-light-tint: #f5f6f9; 77 | } 78 | 79 | @media (prefers-color-scheme: dark) { 80 | /* 81 | * Dark Colors 82 | * ------------------------------------------- 83 | */ 84 | 85 | body { 86 | --ion-color-primary: #428cff; 87 | --ion-color-primary-rgb: 66,140,255; 88 | --ion-color-primary-contrast: #ffffff; 89 | --ion-color-primary-contrast-rgb: 255,255,255; 90 | --ion-color-primary-shade: #3a7be0; 91 | --ion-color-primary-tint: #5598ff; 92 | 93 | --ion-color-secondary: #50c8ff; 94 | --ion-color-secondary-rgb: 80,200,255; 95 | --ion-color-secondary-contrast: #ffffff; 96 | --ion-color-secondary-contrast-rgb: 255,255,255; 97 | --ion-color-secondary-shade: #46b0e0; 98 | --ion-color-secondary-tint: #62ceff; 99 | 100 | --ion-color-tertiary: #6a64ff; 101 | --ion-color-tertiary-rgb: 106,100,255; 102 | --ion-color-tertiary-contrast: #ffffff; 103 | --ion-color-tertiary-contrast-rgb: 255,255,255; 104 | --ion-color-tertiary-shade: #5d58e0; 105 | --ion-color-tertiary-tint: #7974ff; 106 | 107 | --ion-color-success: #2fdf75; 108 | --ion-color-success-rgb: 47,223,117; 109 | --ion-color-success-contrast: #000000; 110 | --ion-color-success-contrast-rgb: 0,0,0; 111 | --ion-color-success-shade: #29c467; 112 | --ion-color-success-tint: #44e283; 113 | 114 | --ion-color-warning: #ffd534; 115 | --ion-color-warning-rgb: 255,213,52; 116 | --ion-color-warning-contrast: #000000; 117 | --ion-color-warning-contrast-rgb: 0,0,0; 118 | --ion-color-warning-shade: #e0bb2e; 119 | --ion-color-warning-tint: #ffd948; 120 | 121 | --ion-color-danger: #ff4961; 122 | --ion-color-danger-rgb: 255,73,97; 123 | --ion-color-danger-contrast: #ffffff; 124 | --ion-color-danger-contrast-rgb: 255,255,255; 125 | --ion-color-danger-shade: #e04055; 126 | --ion-color-danger-tint: #ff5b71; 127 | 128 | --ion-color-dark: #f4f5f8; 129 | --ion-color-dark-rgb: 244,245,248; 130 | --ion-color-dark-contrast: #000000; 131 | --ion-color-dark-contrast-rgb: 0,0,0; 132 | --ion-color-dark-shade: #d7d8da; 133 | --ion-color-dark-tint: #f5f6f9; 134 | 135 | --ion-color-medium: #989aa2; 136 | --ion-color-medium-rgb: 152,154,162; 137 | --ion-color-medium-contrast: #000000; 138 | --ion-color-medium-contrast-rgb: 0,0,0; 139 | --ion-color-medium-shade: #86888f; 140 | --ion-color-medium-tint: #a2a4ab; 141 | 142 | --ion-color-light: #222428; 143 | --ion-color-light-rgb: 34,36,40; 144 | --ion-color-light-contrast: #ffffff; 145 | --ion-color-light-contrast-rgb: 255,255,255; 146 | --ion-color-light-shade: #1e2023; 147 | --ion-color-light-tint: #383a3e; 148 | } 149 | 150 | /* 151 | * iOS Dark Theme 152 | * ------------------------------------------- 153 | */ 154 | 155 | .ios body { 156 | --ion-background-color: #000000; 157 | --ion-background-color-rgb: 0,0,0; 158 | 159 | --ion-text-color: #ffffff; 160 | --ion-text-color-rgb: 255,255,255; 161 | 162 | --ion-color-step-50: #0d0d0d; 163 | --ion-color-step-100: #1a1a1a; 164 | --ion-color-step-150: #262626; 165 | --ion-color-step-200: #333333; 166 | --ion-color-step-250: #404040; 167 | --ion-color-step-300: #4d4d4d; 168 | --ion-color-step-350: #595959; 169 | --ion-color-step-400: #666666; 170 | --ion-color-step-450: #737373; 171 | --ion-color-step-500: #808080; 172 | --ion-color-step-550: #8c8c8c; 173 | --ion-color-step-600: #999999; 174 | --ion-color-step-650: #a6a6a6; 175 | --ion-color-step-700: #b3b3b3; 176 | --ion-color-step-750: #bfbfbf; 177 | --ion-color-step-800: #cccccc; 178 | --ion-color-step-850: #d9d9d9; 179 | --ion-color-step-900: #e6e6e6; 180 | --ion-color-step-950: #f2f2f2; 181 | 182 | --ion-item-background: #000000; 183 | 184 | --ion-card-background: #1c1c1d; 185 | } 186 | 187 | .ios ion-modal { 188 | --ion-background-color: var(--ion-color-step-100); 189 | --ion-toolbar-background: var(--ion-color-step-150); 190 | --ion-toolbar-border-color: var(--ion-color-step-250); 191 | } 192 | 193 | 194 | /* 195 | * Material Design Dark Theme 196 | * ------------------------------------------- 197 | */ 198 | 199 | .md body { 200 | --ion-background-color: #121212; 201 | --ion-background-color-rgb: 18,18,18; 202 | 203 | --ion-text-color: #ffffff; 204 | --ion-text-color-rgb: 255,255,255; 205 | 206 | --ion-border-color: #222222; 207 | 208 | --ion-color-step-50: #1e1e1e; 209 | --ion-color-step-100: #2a2a2a; 210 | --ion-color-step-150: #363636; 211 | --ion-color-step-200: #414141; 212 | --ion-color-step-250: #4d4d4d; 213 | --ion-color-step-300: #595959; 214 | --ion-color-step-350: #656565; 215 | --ion-color-step-400: #717171; 216 | --ion-color-step-450: #7d7d7d; 217 | --ion-color-step-500: #898989; 218 | --ion-color-step-550: #949494; 219 | --ion-color-step-600: #a0a0a0; 220 | --ion-color-step-650: #acacac; 221 | --ion-color-step-700: #b8b8b8; 222 | --ion-color-step-750: #c4c4c4; 223 | --ion-color-step-800: #d0d0d0; 224 | --ion-color-step-850: #dbdbdb; 225 | --ion-color-step-900: #e7e7e7; 226 | --ion-color-step-950: #f3f3f3; 227 | 228 | --ion-item-background: #1e1e1e; 229 | 230 | --ion-toolbar-background: #1f1f1f; 231 | 232 | --ion-tab-bar-background: #1f1f1f; 233 | 234 | --ion-card-background: #1e1e1e; 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /demo-ionic-angular/src/zone-flags.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Prevents Angular change detection from 3 | * running with certain Web Component callbacks 4 | */ 5 | // eslint-disable-next-line no-underscore-dangle 6 | (window as any).__Zone_disable_customElements = true; 7 | -------------------------------------------------------------------------------- /demo-ionic-angular/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts", 10 | "src/polyfills.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /demo-ionic-angular/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "baseUrl": "./", 6 | "outDir": "./dist/out-tsc", 7 | "forceConsistentCasingInFileNames": true, 8 | "strict": true, 9 | "noImplicitOverride": true, 10 | "noPropertyAccessFromIndexSignature": true, 11 | "noImplicitReturns": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "sourceMap": true, 14 | "declaration": false, 15 | "downlevelIteration": true, 16 | "experimentalDecorators": true, 17 | "moduleResolution": "node", 18 | "importHelpers": true, 19 | "target": "es2022", 20 | "module": "es2020", 21 | "lib": [ 22 | "es2018", 23 | "dom" 24 | ], 25 | "useDefineForClassFields": false 26 | }, 27 | "angularCompilerOptions": { 28 | "enableI18nLegacyMessageIdFormat": false, 29 | "strictInjectionParameters": true, 30 | "strictInputAccessModifiers": true, 31 | "strictTemplates": true 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /demo-ionic-angular/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /demo/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /demo/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | speed-measure-plugin*.json 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | *.sublime-workspace 25 | 26 | # IDE - VSCode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | .history/* 33 | 34 | # misc 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /demo/README.md: -------------------------------------------------------------------------------- 1 | # Demo 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.3.14. 4 | 5 | ## Development server 6 | 7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 12 | 13 | ## Build 14 | 15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | 25 | ## Further help 26 | 27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 28 | -------------------------------------------------------------------------------- /demo/android/.gitignore: -------------------------------------------------------------------------------- 1 | # NPM renames .gitignore to .npmignore 2 | # In order to prevent that, we remove the initial "." 3 | # And the CLI then renames it 4 | 5 | # Using Android gitignore template: https://github.com/github/gitignore/blob/master/Android.gitignore 6 | 7 | # Built application files 8 | *.apk 9 | *.ap_ 10 | *.aab 11 | 12 | # Files for the ART/Dalvik VM 13 | *.dex 14 | 15 | # Java class files 16 | *.class 17 | 18 | # Generated files 19 | bin/ 20 | gen/ 21 | out/ 22 | release/ 23 | 24 | # Gradle files 25 | .gradle/ 26 | build/ 27 | 28 | # Local configuration file (sdk path, etc) 29 | local.properties 30 | 31 | # Proguard folder generated by Eclipse 32 | proguard/ 33 | 34 | # Log Files 35 | *.log 36 | 37 | # Android Studio Navigation editor temp files 38 | .navigation/ 39 | 40 | # Android Studio captures folder 41 | captures/ 42 | 43 | # IntelliJ 44 | *.iml 45 | .idea/workspace.xml 46 | .idea/tasks.xml 47 | .idea/gradle.xml 48 | .idea/assetWizardSettings.xml 49 | .idea/dictionaries 50 | .idea/libraries 51 | # Android Studio 3 in .gitignore file. 52 | .idea/caches 53 | .idea/modules.xml 54 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 55 | .idea/navEditor.xml 56 | 57 | # Keystore files 58 | # Uncomment the following lines if you do not want to check your keystore files in. 59 | #*.jks 60 | #*.keystore 61 | 62 | # External native build folder generated in Android Studio 2.2 and later 63 | .externalNativeBuild 64 | 65 | # Freeline 66 | freeline.py 67 | freeline/ 68 | freeline_project_description.json 69 | 70 | # fastlane 71 | fastlane/report.xml 72 | fastlane/Preview.html 73 | fastlane/screenshots 74 | fastlane/test_output 75 | fastlane/readme.md 76 | 77 | # Version control 78 | vcs.xml 79 | 80 | # lint 81 | lint/intermediates/ 82 | lint/generated/ 83 | lint/outputs/ 84 | lint/tmp/ 85 | # lint/reports/ 86 | 87 | # Cordova plugins for Capacitor 88 | capacitor-cordova-android-plugins 89 | 90 | # Copied web assets 91 | app/src/main/assets/public 92 | -------------------------------------------------------------------------------- /demo/android/.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | xmlns:android 14 | 15 | ^$ 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 | xmlns:.* 25 | 26 | ^$ 27 | 28 | 29 | BY_NAME 30 | 31 |
32 |
33 | 34 | 35 | 36 | .*:id 37 | 38 | http://schemas.android.com/apk/res/android 39 | 40 | 41 | 42 |
43 |
44 | 45 | 46 | 47 | .*:name 48 | 49 | http://schemas.android.com/apk/res/android 50 | 51 | 52 | 53 |
54 |
55 | 56 | 57 | 58 | name 59 | 60 | ^$ 61 | 62 | 63 | 64 |
65 |
66 | 67 | 68 | 69 | style 70 | 71 | ^$ 72 | 73 | 74 | 75 |
76 |
77 | 78 | 79 | 80 | .* 81 | 82 | ^$ 83 | 84 | 85 | BY_NAME 86 | 87 |
88 |
89 | 90 | 91 | 92 | .* 93 | 94 | http://schemas.android.com/apk/res/android 95 | 96 | 97 | ANDROID_ATTRIBUTE_ORDER 98 | 99 |
100 |
101 | 102 | 103 | 104 | .* 105 | 106 | .* 107 | 108 | 109 | BY_NAME 110 | 111 |
112 |
113 |
114 |
115 |
116 |
-------------------------------------------------------------------------------- /demo/android/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /demo/android/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /demo/android/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /demo/android/app/.npmignore: -------------------------------------------------------------------------------- 1 | /build/* 2 | !/build/.npmkeep 3 | -------------------------------------------------------------------------------- /demo/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | defaultConfig { 6 | applicationId "com.example.app" 7 | minSdkVersion 21 8 | targetSdkVersion 28 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | repositories { 22 | maven { 23 | url "https://dl.bintray.com/ionic-team/capacitor" 24 | } 25 | flatDir{ 26 | dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs' 27 | } 28 | } 29 | 30 | dependencies { 31 | implementation fileTree(include: ['*.jar'], dir: 'libs') 32 | implementation 'com.android.support:appcompat-v7:28.0.0' 33 | implementation project(':capacitor-android') 34 | testImplementation 'junit:junit:4.12' 35 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 36 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 37 | implementation project(':capacitor-cordova-android-plugins') 38 | } 39 | 40 | apply from: 'capacitor.build.gradle' 41 | 42 | try { 43 | def servicesJSON = file('google-services.json') 44 | if (servicesJSON.text) { 45 | apply plugin: 'com.google.gms.google-services' 46 | } 47 | } catch(Exception e) { 48 | logger.warn("google-services.json not found, google-services plugin not applied. Push Notifications won't work") 49 | } -------------------------------------------------------------------------------- /demo/android/app/capacitor.build.gradle: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN 2 | 3 | android { 4 | compileOptions { 5 | sourceCompatibility JavaVersion.VERSION_1_8 6 | targetCompatibility JavaVersion.VERSION_1_8 7 | } 8 | } 9 | 10 | apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" 11 | dependencies { 12 | implementation project(':codetrix-studio-capacitor-google-auth') 13 | 14 | } 15 | 16 | 17 | if (hasProperty('postBuildExtras')) { 18 | postBuildExtras() 19 | } 20 | -------------------------------------------------------------------------------- /demo/android/app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "744254868856", 4 | "firebase_url": "https://fir-9432d.firebaseio.com", 5 | "project_id": "fir-9432d", 6 | "storage_bucket": "fir-9432d.appspot.com" 7 | }, 8 | "client": [ 9 | { 10 | "client_info": { 11 | "mobilesdk_app_id": "1:744254868856:android:c5be73ef5e59465bd20c8d", 12 | "android_client_info": { 13 | "package_name": "com.example.app" 14 | } 15 | }, 16 | "oauth_client": [ 17 | { 18 | "client_id": "744254868856-6j8dflcgq0tiqt0b506b61etukcq3rdm.apps.googleusercontent.com", 19 | "client_type": 3 20 | } 21 | ], 22 | "api_key": [ 23 | { 24 | "current_key": "AIzaSyAe4dbuIzQi47-zYOrmupP7LM-GC2ByQYc" 25 | } 26 | ], 27 | "services": { 28 | "appinvite_service": { 29 | "other_platform_oauth_client": [ 30 | { 31 | "client_id": "744254868856-6j8dflcgq0tiqt0b506b61etukcq3rdm.apps.googleusercontent.com", 32 | "client_type": 3 33 | }, 34 | { 35 | "client_id": "744254868856-d21fmkjhkulq9m9dqm59devmk5qd95nk.apps.googleusercontent.com", 36 | "client_type": 2, 37 | "ios_info": { 38 | "bundle_id": "com.example.app" 39 | } 40 | } 41 | ] 42 | } 43 | } 44 | } 45 | ], 46 | "configuration_version": "1" 47 | } -------------------------------------------------------------------------------- /demo/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /demo/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.getcapacitor.myapp; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.getcapacitor.app", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /demo/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 39 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /demo/android/app/src/main/assets/capacitor.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "appId": "com.example.app", 3 | "appName": "demo", 4 | "bundledWebRuntime": false, 5 | "npmClient": "npm", 6 | "webDir": "dist/demo", 7 | "cordova": {}, 8 | "plugins": { 9 | "GoogleAuth": { 10 | "scopes": ["profile", "email"], 11 | "serverClientId": "744254868856-6j8dflcgq0tiqt0b506b61etukcq3rdm.apps.googleusercontent.com" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /demo/android/app/src/main/java/com/example/app/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.app; 2 | 3 | import android.os.Bundle; 4 | 5 | import com.codetrixstudio.capacitor.GoogleAuth.GoogleAuth; 6 | import com.getcapacitor.BridgeActivity; 7 | import com.getcapacitor.Plugin; 8 | 9 | import java.util.ArrayList; 10 | 11 | public class MainActivity extends BridgeActivity { 12 | @Override 13 | public void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | 16 | // Initializes the Bridge 17 | this.init(savedInstanceState, new ArrayList>() {{ 18 | // Additional plugins you've installed go here 19 | // Ex: add(TotallyAwesomePlugin.class); 20 | add(GoogleAuth.class); 21 | }}); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /demo/android/app/src/main/res/drawable-land-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/drawable-land-hdpi/splash.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/drawable-land-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/drawable-land-mdpi/splash.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/drawable-land-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/drawable-land-xhdpi/splash.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/drawable-land-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/drawable-land-xxhdpi/splash.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/drawable-land-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/drawable-land-xxxhdpi/splash.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/drawable-port-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/drawable-port-hdpi/splash.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/drawable-port-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/drawable-port-mdpi/splash.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/drawable-port-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/drawable-port-xhdpi/splash.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/drawable-port-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/drawable-port-xxhdpi/splash.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/drawable-port-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/drawable-port-xxxhdpi/splash.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /demo/android/app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /demo/android/app/src/main/res/drawable/launch_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /demo/android/app/src/main/res/drawable/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/drawable/splash.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /demo/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /demo/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /demo/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /demo/android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /demo/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | demo 4 | demo 5 | com.example.app 6 | com.example.app 7 | 744254868856-gud37co8eephv9slgpo6injpvtca59o7.apps.googleusercontent.com 8 | 9 | -------------------------------------------------------------------------------- /demo/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 17 | 18 | 19 | 22 | -------------------------------------------------------------------------------- /demo/android/app/src/main/res/xml/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /demo/android/app/src/main/res/xml/file_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /demo/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.getcapacitor.myapp; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /demo/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.4.1' 11 | classpath 'com.google.gms:google-services:4.2.0' 12 | 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | allprojects { 19 | repositories { 20 | google() 21 | jcenter() 22 | } 23 | } 24 | 25 | task clean(type: Delete) { 26 | delete rootProject.buildDir 27 | } 28 | -------------------------------------------------------------------------------- /demo/android/capacitor.settings.gradle: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN 2 | include ':capacitor-android' 3 | project(':capacitor-android').projectDir = new File('../../node_modules/@capacitor/android/capacitor') 4 | 5 | include ':codetrix-studio-capacitor-google-auth' 6 | project(':codetrix-studio-capacitor-google-auth').projectDir = new File('../node_modules/@codetrix-studio/capacitor-google-auth/android') 7 | -------------------------------------------------------------------------------- /demo/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /demo/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /demo/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Oct 25 00:08:40 IST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip 7 | -------------------------------------------------------------------------------- /demo/android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /demo/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /demo/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | include ':capacitor-cordova-android-plugins' 3 | project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/') 4 | 5 | apply from: 'capacitor.settings.gradle' -------------------------------------------------------------------------------- /demo/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "demo": { 7 | "projectType": "application", 8 | "schematics": { 9 | "@schematics/angular:component": { 10 | "style": "scss" 11 | } 12 | }, 13 | "root": "", 14 | "sourceRoot": "src", 15 | "prefix": "app", 16 | "architect": { 17 | "build": { 18 | "builder": "@angular-devkit/build-angular:browser", 19 | "options": { 20 | "outputPath": "dist/demo", 21 | "index": "src/index.html", 22 | "main": "src/main.ts", 23 | "polyfills": "src/polyfills.ts", 24 | "tsConfig": "tsconfig.app.json", 25 | "aot": false, 26 | "assets": [ 27 | "src/favicon.ico", 28 | "src/assets" 29 | ], 30 | "styles": [ 31 | "src/styles.scss", 32 | { 33 | "input": "./node_modules/bootstrap/dist/css/bootstrap.css" 34 | } 35 | ], 36 | "scripts": [] 37 | }, 38 | "configurations": { 39 | "production": { 40 | "fileReplacements": [ 41 | { 42 | "replace": "src/environments/environment.ts", 43 | "with": "src/environments/environment.prod.ts" 44 | } 45 | ], 46 | "optimization": true, 47 | "outputHashing": "all", 48 | "sourceMap": false, 49 | "extractCss": true, 50 | "namedChunks": false, 51 | "aot": true, 52 | "extractLicenses": true, 53 | "vendorChunk": false, 54 | "buildOptimizer": true, 55 | "budgets": [ 56 | { 57 | "type": "initial", 58 | "maximumWarning": "2mb", 59 | "maximumError": "5mb" 60 | }, 61 | { 62 | "type": "anyComponentStyle", 63 | "maximumWarning": "6kb", 64 | "maximumError": "10kb" 65 | } 66 | ] 67 | } 68 | } 69 | }, 70 | "serve": { 71 | "builder": "@angular-devkit/build-angular:dev-server", 72 | "options": { 73 | "browserTarget": "demo:build" 74 | }, 75 | "configurations": { 76 | "production": { 77 | "browserTarget": "demo:build:production" 78 | } 79 | } 80 | }, 81 | "extract-i18n": { 82 | "builder": "@angular-devkit/build-angular:extract-i18n", 83 | "options": { 84 | "browserTarget": "demo:build" 85 | } 86 | }, 87 | "test": { 88 | "builder": "@angular-devkit/build-angular:karma", 89 | "options": { 90 | "main": "src/test.ts", 91 | "polyfills": "src/polyfills.ts", 92 | "tsConfig": "tsconfig.spec.json", 93 | "karmaConfig": "karma.conf.js", 94 | "assets": [ 95 | "src/favicon.ico", 96 | "src/assets" 97 | ], 98 | "styles": [ 99 | "src/styles.scss" 100 | ], 101 | "scripts": [] 102 | } 103 | }, 104 | "lint": { 105 | "builder": "@angular-devkit/build-angular:tslint", 106 | "options": { 107 | "tsConfig": [ 108 | "tsconfig.app.json", 109 | "tsconfig.spec.json", 110 | "e2e/tsconfig.json" 111 | ], 112 | "exclude": [ 113 | "**/node_modules/**" 114 | ] 115 | } 116 | }, 117 | "e2e": { 118 | "builder": "@angular-devkit/build-angular:protractor", 119 | "options": { 120 | "protractorConfig": "e2e/protractor.conf.js", 121 | "devServerTarget": "demo:serve" 122 | }, 123 | "configurations": { 124 | "production": { 125 | "devServerTarget": "demo:serve:production" 126 | } 127 | } 128 | } 129 | } 130 | } 131 | }, 132 | "defaultProject": "demo" 133 | } -------------------------------------------------------------------------------- /demo/browserslist: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /demo/capacitor.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "appId": "com.example.app", 3 | "appName": "demo", 4 | "bundledWebRuntime": false, 5 | "npmClient": "npm", 6 | "webDir": "dist/demo", 7 | "cordova": {}, 8 | "plugins": { 9 | "GoogleAuth": { 10 | "scopes": ["profile", "email"], 11 | "serverClientId": "744254868856-6j8dflcgq0tiqt0b506b61etukcq3rdm.apps.googleusercontent.com", 12 | "forceCodeForRefreshToken" : true 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /demo/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | browserName: 'chrome' 17 | }, 18 | directConnect: true, 19 | baseUrl: 'http://localhost:4200/', 20 | framework: 'jasmine', 21 | jasmineNodeOpts: { 22 | showColors: true, 23 | defaultTimeoutInterval: 30000, 24 | print: function() {} 25 | }, 26 | onPrepare() { 27 | require('ts-node').register({ 28 | project: require('path').join(__dirname, './tsconfig.json') 29 | }); 30 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 31 | } 32 | }; -------------------------------------------------------------------------------- /demo/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('demo app is running!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /demo/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText() { 9 | return element(by.css('app-root .content span')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /demo/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /demo/ios/.gitignore: -------------------------------------------------------------------------------- 1 | # NPM renames .gitignore to .npmignore 2 | # In order to prevent that, we remove the initial "." 3 | # And the CLI then renames it 4 | 5 | App/build 6 | App/Pods 7 | App/public 8 | App/Podfile.lock 9 | xcuserdata 10 | 11 | # Cordova plugins for Capacitor 12 | capacitor-cordova-ios-plugins 13 | 14 | -------------------------------------------------------------------------------- /demo/ios/App/App.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /demo/ios/App/App.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /demo/ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /demo/ios/App/App/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Capacitor 3 | 4 | @UIApplicationMain 5 | class AppDelegate: UIResponder, UIApplicationDelegate { 6 | 7 | var window: UIWindow? 8 | 9 | 10 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 11 | // Override point for customization after application launch. 12 | return true 13 | } 14 | 15 | func applicationWillResignActive(_ application: UIApplication) { 16 | // 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. 17 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 18 | } 19 | 20 | func applicationDidEnterBackground(_ application: UIApplication) { 21 | // 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. 22 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 23 | } 24 | 25 | func applicationWillEnterForeground(_ application: UIApplication) { 26 | // 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. 27 | } 28 | 29 | func applicationDidBecomeActive(_ application: UIApplication) { 30 | // 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. 31 | } 32 | 33 | func applicationWillTerminate(_ application: UIApplication) { 34 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 35 | } 36 | 37 | func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { 38 | // Called when the app was launched with a url. Feel free to add additional processing here, 39 | // but if you want the App API to support tracking app url opens, make sure to keep this call 40 | return CAPBridge.handleOpenUrl(url, options) 41 | } 42 | 43 | func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { 44 | // Called when the app was launched with an activity, including Universal Links. 45 | // Feel free to add additional processing here, but if you want the App API to support 46 | // tracking app url opens, make sure to keep this call 47 | return CAPBridge.handleContinueActivity(userActivity, restorationHandler) 48 | } 49 | 50 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 51 | super.touchesBegan(touches, with: event) 52 | 53 | let statusBarRect = UIApplication.shared.statusBarFrame 54 | guard let touchPoint = event?.allTouches?.first?.location(in: self.window) else { return } 55 | 56 | if statusBarRect.contains(touchPoint) { 57 | NotificationCenter.default.post(CAPBridge.statusBarTappedNotification) 58 | } 59 | } 60 | 61 | #if USE_PUSH 62 | 63 | func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { 64 | NotificationCenter.default.post(name: Notification.Name(CAPNotifications.DidRegisterForRemoteNotificationsWithDeviceToken.name()), object: deviceToken) 65 | } 66 | 67 | func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { 68 | NotificationCenter.default.post(name: Notification.Name(CAPNotifications.DidFailToRegisterForRemoteNotificationsWithError.name()), object: error) 69 | } 70 | 71 | #endif 72 | 73 | } 74 | 75 | -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@1x.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x-1.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@3x.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@1x.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x-1.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@3x.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@1x.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x-1.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@3x.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@2x.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@3x.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@1x.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@2x.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5x83.5@2x.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 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 | } -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json: -------------------------------------------------------------------------------- 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 | } -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png -------------------------------------------------------------------------------- /demo/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png -------------------------------------------------------------------------------- /demo/ios/App/App/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /demo/ios/App/App/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /demo/ios/App/App/GoogleService-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CLIENT_ID 6 | 744254868856-d21fmkjhkulq9m9dqm59devmk5qd95nk.apps.googleusercontent.com 7 | REVERSED_CLIENT_ID 8 | com.googleusercontent.apps.744254868856-d21fmkjhkulq9m9dqm59devmk5qd95nk 9 | API_KEY 10 | AIzaSyDcsvdMFLFd_Eqy-tni6Dnnkp5NgvquRIg 11 | GCM_SENDER_ID 12 | 744254868856 13 | PLIST_VERSION 14 | 1 15 | BUNDLE_ID 16 | com.example.app 17 | PROJECT_ID 18 | fir-9432d 19 | STORAGE_BUCKET 20 | fir-9432d.appspot.com 21 | IS_ADS_ENABLED 22 | 23 | IS_ANALYTICS_ENABLED 24 | 25 | IS_APPINVITE_ENABLED 26 | 27 | IS_GCM_ENABLED 28 | 29 | IS_SIGNIN_ENABLED 30 | 31 | GOOGLE_APP_ID 32 | 1:744254868856:ios:0952c8c9f93c8d07d20c8d 33 | DATABASE_URL 34 | https://fir-9432d.firebaseio.com 35 | 36 | -------------------------------------------------------------------------------- /demo/ios/App/App/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | demo 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleURLTypes 22 | 23 | 24 | CFBundleURLName 25 | com.getcapacitor.capacitor 26 | CFBundleURLSchemes 27 | 28 | capacitor 29 | com.googleusercontent.apps.744254868856-d21fmkjhkulq9m9dqm59devmk5qd95nk 30 | 31 | 32 | 33 | CFBundleVersion 34 | 1 35 | LSRequiresIPhoneOS 36 | 37 | NSAppTransportSecurity 38 | 39 | NSAllowsArbitraryLoads 40 | 41 | 42 | NSCameraUsageDescription 43 | To Take Photos and Video 44 | NSLocationAlwaysUsageDescription 45 | Always allow Geolocation? 46 | NSLocationWhenInUseUsageDescription 47 | Allow Geolocation? 48 | NSMicrophoneUsageDescription 49 | To Record Audio With Video 50 | NSPhotoLibraryAddUsageDescription 51 | Store camera photos to camera 52 | NSPhotoLibraryUsageDescription 53 | To Pick Photos from Library 54 | UILaunchStoryboardName 55 | LaunchScreen 56 | UIMainStoryboardFile 57 | Main 58 | UIRequiredDeviceCapabilities 59 | 60 | armv7 61 | 62 | UISupportedInterfaceOrientations 63 | 64 | UIInterfaceOrientationPortrait 65 | UIInterfaceOrientationLandscapeLeft 66 | UIInterfaceOrientationLandscapeRight 67 | 68 | UISupportedInterfaceOrientations~ipad 69 | 70 | UIInterfaceOrientationPortrait 71 | UIInterfaceOrientationPortraitUpsideDown 72 | UIInterfaceOrientationLandscapeLeft 73 | UIInterfaceOrientationLandscapeRight 74 | 75 | UIViewControllerBasedStatusBarAppearance 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /demo/ios/App/App/capacitor.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "appId": "com.example.app", 3 | "appName": "demo", 4 | "bundledWebRuntime": false, 5 | "npmClient": "npm", 6 | "webDir": "dist/demo", 7 | "cordova": {}, 8 | "plugins": { 9 | "GoogleAuth": { 10 | "scopes": ["profile", "email"], 11 | "serverClientId": "744254868856-6j8dflcgq0tiqt0b506b61etukcq3rdm.apps.googleusercontent.com" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /demo/ios/App/App/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /demo/ios/App/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '11.0' 2 | use_frameworks! 3 | 4 | # workaround to avoid Xcode 10 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 | # Automatic Capacitor Pod dependencies, do not delete 11 | pod 'Capacitor', :path => '../../../node_modules/@capacitor/ios' 12 | pod 'CapacitorCordova', :path => '../../../node_modules/@capacitor/ios' 13 | pod 'CodetrixStudioCapacitorGoogleAuth', :path => '../../..' 14 | # Do not delete 15 | end 16 | 17 | target 'App' do 18 | capacitor_pods 19 | # Add your Pods here 20 | end 21 | -------------------------------------------------------------------------------- /demo/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, './coverage/demo'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "test": "ng test", 9 | "lint": "ng lint", 10 | "e2e": "ng e2e" 11 | }, 12 | "private": true, 13 | "dependencies": { 14 | "@angular/animations": "~8.2.11", 15 | "@angular/common": "~8.2.11", 16 | "@angular/compiler": "~8.2.11", 17 | "@angular/core": "~8.2.11", 18 | "@angular/forms": "~8.2.11", 19 | "@angular/platform-browser": "~8.2.11", 20 | "@angular/platform-browser-dynamic": "~8.2.11", 21 | "@angular/router": "~8.2.11", 22 | "@capacitor/cli": "^1.3.0", 23 | "@capacitor/core": "^1.3.0", 24 | "@codetrix-studio/capacitor-google-auth": "file:..", 25 | "@ng-bootstrap/schematics": "^2.0.0-alpha.1", 26 | "rxjs": "~6.4.0", 27 | "tslib": "^1.10.0", 28 | "zone.js": "~0.9.1", 29 | "@ng-bootstrap/ng-bootstrap": "^2.0.0-alpha.0", 30 | "bootstrap": "^4.0.0" 31 | }, 32 | "devDependencies": { 33 | "@angular-devkit/build-angular": "~0.803.14", 34 | "@angular/cli": "~8.3.14", 35 | "@angular/compiler-cli": "~8.2.11", 36 | "@angular/language-service": "~8.2.11", 37 | "@types/node": "~8.9.4", 38 | "@types/jasmine": "~3.3.8", 39 | "@types/jasminewd2": "~2.0.3", 40 | "codelyzer": "^5.0.0", 41 | "jasmine-core": "~3.4.0", 42 | "jasmine-spec-reporter": "~4.2.1", 43 | "karma": "~4.1.0", 44 | "karma-chrome-launcher": "~2.2.0", 45 | "karma-coverage-istanbul-reporter": "~2.0.1", 46 | "karma-jasmine": "~2.0.1", 47 | "karma-jasmine-html-reporter": "^1.4.0", 48 | "protractor": "~5.4.0", 49 | "ts-node": "~7.0.0", 50 | "tslint": "~5.15.0", 51 | "typescript": "~3.5.3" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /demo/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | 4 | 5 | const routes: Routes = []; 6 | 7 | @NgModule({ 8 | imports: [RouterModule.forRoot(routes)], 9 | exports: [RouterModule] 10 | }) 11 | export class AppRoutingModule { } 12 | -------------------------------------------------------------------------------- /demo/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 5 |
6 |
7 |
8 |
9 | 10 |
11 |
12 | 13 |
14 |
15 | 16 |
17 |
18 |
19 |
-------------------------------------------------------------------------------- /demo/src/app/app.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/src/app/app.component.scss -------------------------------------------------------------------------------- /demo/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { RouterTestingModule } from '@angular/router/testing'; 3 | import { AppComponent } from './app.component'; 4 | 5 | describe('AppComponent', () => { 6 | beforeEach(async(() => { 7 | TestBed.configureTestingModule({ 8 | imports: [ 9 | RouterTestingModule 10 | ], 11 | declarations: [ 12 | AppComponent 13 | ], 14 | }).compileComponents(); 15 | })); 16 | 17 | it('should create the app', () => { 18 | const fixture = TestBed.createComponent(AppComponent); 19 | const app = fixture.debugElement.componentInstance; 20 | expect(app).toBeTruthy(); 21 | }); 22 | 23 | it(`should have as title 'demo'`, () => { 24 | const fixture = TestBed.createComponent(AppComponent); 25 | const app = fixture.debugElement.componentInstance; 26 | expect(app.title).toEqual('demo'); 27 | }); 28 | 29 | it('should render title', () => { 30 | const fixture = TestBed.createComponent(AppComponent); 31 | fixture.detectChanges(); 32 | const compiled = fixture.debugElement.nativeElement; 33 | expect(compiled.querySelector('.content span').textContent).toContain('demo app is running!'); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /demo/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | import "@codetrix-studio/capacitor-google-auth"; 4 | 5 | import { Plugins } from '@capacitor/core'; 6 | const { SplashScreen, GoogleAuth } = Plugins; 7 | 8 | @Component({ 9 | selector: 'app-root', 10 | templateUrl: './app.component.html', 11 | styleUrls: ['./app.component.scss'] 12 | }) 13 | export class AppComponent implements OnInit { 14 | title = 'demo'; 15 | username: string; 16 | 17 | ngOnInit() { 18 | SplashScreen.hide(); 19 | 20 | GoogleAuth.addListener('userChange', (googleUser) => { 21 | console.log("userChange:", googleUser); 22 | }); 23 | } 24 | 25 | async signIn() { 26 | let googleUser = await GoogleAuth.signIn(); 27 | this.username = googleUser.name; 28 | console.log("signIn:", googleUser); 29 | } 30 | 31 | async refreshToken() { 32 | let response = await GoogleAuth.refresh(); 33 | console.log("refresh:", response); 34 | } 35 | 36 | async signOut() { 37 | await GoogleAuth.signOut(); 38 | this.username = ""; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /demo/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | import { AppRoutingModule } from './app-routing.module'; 5 | import { AppComponent } from './app.component'; 6 | import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; 7 | 8 | @NgModule({ 9 | declarations: [ 10 | AppComponent 11 | ], 12 | imports: [ 13 | BrowserModule, 14 | AppRoutingModule, 15 | NgbModule.forRoot() 16 | ], 17 | providers: [], 18 | bootstrap: [AppComponent] 19 | }) 20 | export class AppModule { } 21 | -------------------------------------------------------------------------------- /demo/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/src/assets/.gitkeep -------------------------------------------------------------------------------- /demo/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /demo/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /demo/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodetrixStudio/CapacitorGoogleAuth/9eb498181718ce109a9cafa0d5918c9876f37777/demo/src/favicon.ico -------------------------------------------------------------------------------- /demo/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Demo 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /demo/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /demo/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 22 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 23 | 24 | /** 25 | * Web Animations `@angular/platform-browser/animations` 26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 28 | */ 29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 30 | 31 | /** 32 | * By default, zone.js will patch all possible macroTask and DomEvents 33 | * user can disable parts of macroTask/DomEvents patch by setting following flags 34 | * because those flags need to be set before `zone.js` being loaded, and webpack 35 | * will put import in the top of bundle, so user need to create a separate file 36 | * in this directory (for example: zone-flags.ts), and put the following flags 37 | * into that file, and then add the following code before importing zone.js. 38 | * import './zone-flags.ts'; 39 | * 40 | * The flags allowed in zone-flags.ts are listed here. 41 | * 42 | * The following flags will work for all browsers. 43 | * 44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 47 | * 48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 50 | * 51 | * (window as any).__Zone_enable_cross_context_check = true; 52 | * 53 | */ 54 | 55 | /*************************************************************************************************** 56 | * Zone JS is required by default for Angular itself. 57 | */ 58 | import 'zone.js/dist/zone'; // Included with Angular CLI. 59 | 60 | 61 | /*************************************************************************************************** 62 | * APPLICATION IMPORTS 63 | */ 64 | -------------------------------------------------------------------------------- /demo/src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /demo/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /demo/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "src/main.ts", 9 | "src/polyfills.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.ts" 13 | ], 14 | "exclude": [ 15 | "src/test.ts", 16 | "src/**/*.spec.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "experimentalDecorators": true, 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "target": "es2015", 14 | "typeRoots": [ 15 | "node_modules/@types" 16 | ], 17 | "lib": [ 18 | "es2018", 19 | "dom" 20 | ] 21 | }, 22 | "angularCompilerOptions": { 23 | "fullTemplateTypeCheck": true, 24 | "strictInjectionParameters": true 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /demo/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /demo/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:recommended", 3 | "rules": { 4 | "array-type": false, 5 | "arrow-parens": false, 6 | "deprecation": { 7 | "severity": "warning" 8 | }, 9 | "component-class-suffix": true, 10 | "contextual-lifecycle": true, 11 | "directive-class-suffix": true, 12 | "directive-selector": [ 13 | true, 14 | "attribute", 15 | "app", 16 | "camelCase" 17 | ], 18 | "component-selector": [ 19 | true, 20 | "element", 21 | "app", 22 | "kebab-case" 23 | ], 24 | "import-blacklist": [ 25 | true, 26 | "rxjs/Rx" 27 | ], 28 | "interface-name": false, 29 | "max-classes-per-file": false, 30 | "max-line-length": [ 31 | true, 32 | 140 33 | ], 34 | "member-access": false, 35 | "member-ordering": [ 36 | true, 37 | { 38 | "order": [ 39 | "static-field", 40 | "instance-field", 41 | "static-method", 42 | "instance-method" 43 | ] 44 | } 45 | ], 46 | "no-consecutive-blank-lines": false, 47 | "no-console": [ 48 | true, 49 | "debug", 50 | "info", 51 | "time", 52 | "timeEnd", 53 | "trace" 54 | ], 55 | "no-empty": false, 56 | "no-inferrable-types": [ 57 | true, 58 | "ignore-params" 59 | ], 60 | "no-non-null-assertion": true, 61 | "no-redundant-jsdoc": true, 62 | "no-switch-case-fall-through": true, 63 | "no-var-requires": false, 64 | "object-literal-key-quotes": [ 65 | true, 66 | "as-needed" 67 | ], 68 | "object-literal-sort-keys": false, 69 | "ordered-imports": false, 70 | "quotemark": [ 71 | true, 72 | "single" 73 | ], 74 | "trailing-comma": false, 75 | "no-conflicting-lifecycle": true, 76 | "no-host-metadata-property": true, 77 | "no-input-rename": true, 78 | "no-inputs-metadata-property": true, 79 | "no-output-native": true, 80 | "no-output-on-prefix": true, 81 | "no-output-rename": true, 82 | "no-outputs-metadata-property": true, 83 | "template-banana-in-box": true, 84 | "template-no-negated-async": true, 85 | "use-lifecycle-interface": true, 86 | "use-pipe-transform-interface": true 87 | }, 88 | "rulesDirectory": [ 89 | "codelyzer" 90 | ] 91 | } -------------------------------------------------------------------------------- /ios/Plugin.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Plugin.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Plugin.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Plugin/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /ios/Plugin/Plugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | //! Project version number for Plugin. 4 | FOUNDATION_EXPORT double PluginVersionNumber; 5 | 6 | //! Project version string for Plugin. 7 | FOUNDATION_EXPORT const unsigned char PluginVersionString[]; 8 | 9 | // In this header, you should import all the public headers of your framework using statements like #import 10 | 11 | -------------------------------------------------------------------------------- /ios/Plugin/Plugin.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | // Define the plugin using the CAP_PLUGIN Macro, and 5 | // each method the plugin supports using the CAP_PLUGIN_METHOD macro. 6 | CAP_PLUGIN(GoogleAuth, "GoogleAuth", 7 | CAP_PLUGIN_METHOD(signIn, CAPPluginReturnPromise); 8 | CAP_PLUGIN_METHOD(refresh, CAPPluginReturnPromise); 9 | CAP_PLUGIN_METHOD(signOut, CAPPluginReturnPromise); 10 | CAP_PLUGIN_METHOD(initialize, CAPPluginReturnPromise); 11 | ) 12 | -------------------------------------------------------------------------------- /ios/Plugin/Plugin.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Capacitor 3 | import GoogleSignIn 4 | 5 | /** 6 | * Please read the Capacitor iOS Plugin Development Guide 7 | * here: https://capacitor.ionicframework.com/docs/plugins/ios 8 | */ 9 | @objc(GoogleAuth) 10 | public class GoogleAuth: CAPPlugin { 11 | var signInCall: CAPPluginCall! 12 | var googleSignIn: GIDSignIn!; 13 | var googleSignInConfiguration: GIDConfiguration!; 14 | var forceAuthCode: Bool = false; 15 | var additionalScopes: [String]!; 16 | 17 | func loadSignInClient ( 18 | customClientId: String, 19 | customScopes: [String] 20 | ) { 21 | googleSignIn = GIDSignIn.sharedInstance; 22 | 23 | let serverClientId = getServerClientIdValue(); 24 | 25 | googleSignInConfiguration = GIDConfiguration.init(clientID: customClientId, serverClientID: serverClientId) 26 | 27 | // these are scopes granted by default by the signIn method 28 | let defaultGrantedScopes = ["email", "profile", "openid"]; 29 | // these are scopes we will need to request after sign in 30 | additionalScopes = customScopes.filter { 31 | return !defaultGrantedScopes.contains($0); 32 | }; 33 | 34 | forceAuthCode = getConfig().getBoolean("forceCodeForRefreshToken", false) 35 | 36 | NotificationCenter.default.addObserver(self, selector: #selector(handleOpenUrl(_ :)), name: Notification.Name(Notification.Name.capacitorOpenURL.rawValue), object: nil); 37 | } 38 | 39 | 40 | public override func load() { 41 | } 42 | 43 | @objc 44 | func initialize(_ call: CAPPluginCall) { 45 | // get client id from initialize, with client id from config file as fallback 46 | guard let clientId = call.getString("clientId") ?? getClientIdValue() as? String else { 47 | NSLog("no client id found in config"); 48 | call.resolve(); 49 | return; 50 | } 51 | 52 | // get scopes from initialize, with scopes from config file as fallback 53 | let customScopes = call.getArray("scopes", String.self) ?? ( 54 | getConfigValue("scopes") as? [String] ?? [] 55 | ); 56 | 57 | // get force auth code from initialize, with config from config file as fallback 58 | forceAuthCode = call.getBool("grantOfflineAccess") ?? ( 59 | getConfigValue("forceCodeForRefreshToken") as? Bool ?? false 60 | ); 61 | 62 | // load client 63 | self.loadSignInClient( 64 | customClientId: clientId, 65 | customScopes: customScopes 66 | ) 67 | call.resolve(); 68 | } 69 | 70 | @objc 71 | func signIn(_ call: CAPPluginCall) { 72 | signInCall = call; 73 | DispatchQueue.main.async { 74 | if self.googleSignIn.hasPreviousSignIn() && !self.forceAuthCode { 75 | self.googleSignIn.restorePreviousSignIn() { user, error in 76 | if let error = error { 77 | self.signInCall?.reject(error.localizedDescription); 78 | return; 79 | } 80 | self.resolveSignInCallWith(user: user!) 81 | } 82 | } else { 83 | let presentingVc = self.bridge!.viewController!; 84 | 85 | self.googleSignIn.signIn(with: self.googleSignInConfiguration, presenting: presentingVc, hint: nil, additionalScopes: self.additionalScopes) { user, error in 86 | if let error = error { 87 | self.signInCall?.reject(error.localizedDescription, "\(error._code)"); 88 | return; 89 | } 90 | self.resolveSignInCallWith(user: user!); 91 | }; 92 | } 93 | } 94 | } 95 | 96 | @objc 97 | func refresh(_ call: CAPPluginCall) { 98 | DispatchQueue.main.async { 99 | if self.googleSignIn.currentUser == nil { 100 | call.reject("User not logged in."); 101 | return 102 | } 103 | self.googleSignIn.currentUser!.authentication.do { (authentication, error) in 104 | guard let authentication = authentication else { 105 | call.reject(error?.localizedDescription ?? "Something went wrong."); 106 | return; 107 | } 108 | let authenticationData: [String: Any] = [ 109 | "accessToken": authentication.accessToken, 110 | "idToken": authentication.idToken ?? NSNull(), 111 | "refreshToken": authentication.refreshToken 112 | ] 113 | call.resolve(authenticationData); 114 | } 115 | } 116 | } 117 | 118 | @objc 119 | func signOut(_ call: CAPPluginCall) { 120 | DispatchQueue.main.async { 121 | if self.googleSignIn != nil { 122 | self.googleSignIn.signOut(); 123 | } 124 | } 125 | call.resolve(); 126 | } 127 | 128 | @objc 129 | func handleOpenUrl(_ notification: Notification) { 130 | guard let object = notification.object as? [String: Any] else { 131 | print("There is no object on handleOpenUrl"); 132 | return; 133 | } 134 | guard let url = object["url"] as? URL else { 135 | print("There is no url on handleOpenUrl"); 136 | return; 137 | } 138 | googleSignIn.handle(url); 139 | } 140 | 141 | 142 | func getClientIdValue() -> String? { 143 | if let clientId = getConfig().getString("iosClientId") { 144 | return clientId; 145 | } 146 | else if let clientId = getConfig().getString("clientId") { 147 | return clientId; 148 | } 149 | else if let path = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist"), 150 | let dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject], 151 | let clientId = dict["CLIENT_ID"] as? String { 152 | return clientId; 153 | } 154 | return nil; 155 | } 156 | 157 | func getServerClientIdValue() -> String? { 158 | if let serverClientId = getConfig().getString("serverClientId") { 159 | return serverClientId; 160 | } 161 | return nil; 162 | } 163 | 164 | func resolveSignInCallWith(user: GIDGoogleUser) { 165 | var userData: [String: Any] = [ 166 | "authentication": [ 167 | "accessToken": user.authentication.accessToken, 168 | "idToken": user.authentication.idToken, 169 | "refreshToken": user.authentication.refreshToken 170 | ], 171 | "serverAuthCode": user.serverAuthCode ?? NSNull(), 172 | "email": user.profile?.email ?? NSNull(), 173 | "familyName": user.profile?.familyName ?? NSNull(), 174 | "givenName": user.profile?.givenName ?? NSNull(), 175 | "id": user.userID ?? NSNull(), 176 | "name": user.profile?.name ?? NSNull() 177 | ]; 178 | if let imageUrl = user.profile?.imageURL(withDimension: 100)?.absoluteString { 179 | userData["imageUrl"] = imageUrl; 180 | } 181 | signInCall?.resolve(userData); 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /ios/PluginTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ios/PluginTests/PluginTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import Capacitor 3 | @testable import Plugin 4 | 5 | class PluginTests: XCTestCase { 6 | 7 | override func setUp() { 8 | super.setUp() 9 | // Put setup code here. This method is called before the invocation of each test method in the class. 10 | } 11 | 12 | override func tearDown() { 13 | // Put teardown code here. This method is called after the invocation of each test method in the class. 14 | super.tearDown() 15 | } 16 | 17 | func testEcho() { 18 | // This is an example of a functional test case for a plugin. 19 | // Use XCTAssert and related functions to verify your tests produce the correct results. 20 | 21 | let value = "Hello, World!" 22 | let plugin = MyPlugin() 23 | 24 | let call = CAPPluginCall(callbackId: "test", options: [ 25 | "value": value 26 | ], success: { (result, call) in 27 | let resultValue = result!.data["value"] as? String 28 | XCTAssertEqual(value, resultValue) 29 | }, error: { (err) in 30 | XCTFail("Error shouldn't have been called") 31 | }) 32 | 33 | plugin.echo(call!) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../../node_modules/@capacitor/ios/scripts/pods_helpers' 2 | 3 | platform :ios, '13.0' 4 | 5 | target 'Plugin' do 6 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 7 | use_frameworks! 8 | pod 'Capacitor', :path => '../node_modules/@capacitor/ios' 9 | pod 'CapacitorCordova', :path => '../node_modules/@capacitor/ios' 10 | 11 | pod 'GoogleSignIn', '~> 6.2.4' 12 | 13 | end 14 | 15 | target 'PluginTests' do 16 | use_frameworks! 17 | 18 | pod 'Capacitor', :path => '../node_modules/@capacitor/ios' 19 | end 20 | 21 | post_install do |installer| 22 | assertDeploymentTarget(installer) 23 | end -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AppAuth (1.6.2): 3 | - AppAuth/Core (= 1.6.2) 4 | - AppAuth/ExternalUserAgent (= 1.6.2) 5 | - AppAuth/Core (1.6.2) 6 | - AppAuth/ExternalUserAgent (1.6.2): 7 | - AppAuth/Core 8 | - Capacitor (5.0.4): 9 | - CapacitorCordova 10 | - CapacitorCordova (5.0.4) 11 | - GoogleSignIn (6.2.4): 12 | - AppAuth (~> 1.5) 13 | - GTMAppAuth (~> 1.3) 14 | - GTMSessionFetcher/Core (< 3.0, >= 1.1) 15 | - GTMAppAuth (1.3.1): 16 | - AppAuth/Core (~> 1.6) 17 | - GTMSessionFetcher/Core (< 3.0, >= 1.5) 18 | - GTMSessionFetcher/Core (2.3.0) 19 | 20 | DEPENDENCIES: 21 | - "Capacitor (from `../node_modules/@capacitor/ios`)" 22 | - "CapacitorCordova (from `../node_modules/@capacitor/ios`)" 23 | - GoogleSignIn (~> 6.2.0) 24 | 25 | SPEC REPOS: 26 | trunk: 27 | - AppAuth 28 | - GoogleSignIn 29 | - GTMAppAuth 30 | - GTMSessionFetcher 31 | 32 | EXTERNAL SOURCES: 33 | Capacitor: 34 | :path: "../node_modules/@capacitor/ios" 35 | CapacitorCordova: 36 | :path: "../node_modules/@capacitor/ios" 37 | 38 | SPEC CHECKSUMS: 39 | AppAuth: 3bb1d1cd9340bd09f5ed189fb00b1cc28e1e8570 40 | Capacitor: d3d4463573438b9fa65326d1f3549da6f4c21634 41 | CapacitorCordova: b1fe6bf1f36974a8e4a9044b342d22d49c0996d6 42 | GoogleSignIn: 5651ce3a61e56ca864160e79b484cd9ed3f49b7a 43 | GTMAppAuth: 0ff230db599948a9ad7470ca667337803b3fc4dd 44 | GTMSessionFetcher: 3a63d75eecd6aa32c2fc79f578064e1214dfdec2 45 | 46 | PODFILE CHECKSUM: f37796f40e1c9a0233c6f7494f01210c0cedf4f7 47 | 48 | COCOAPODS: 1.12.1 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@codetrix-studio/capacitor-google-auth", 3 | "version": "3.4.0-rc.4", 4 | "description": "Google Auth plugin for capacitor.", 5 | "main": "dist/esm/index.js", 6 | "types": "dist/esm/index.d.ts", 7 | "scripts": { 8 | "build": "npm run clean && tsc", 9 | "clean": "rm -rf ./dist", 10 | "watch": "tsc --watch", 11 | "prepublishOnly": "npm run build", 12 | "prepare": "tsc", 13 | "test": "echo \"no test specified\"", 14 | "docgen": "docgen --api GoogleAuthPlugin --output-readme README.md" 15 | }, 16 | "author": "CodetrixStudio", 17 | "license": "MIT", 18 | "devDependencies": { 19 | "@capacitor/android": "^6.0.0", 20 | "@capacitor/cli": "^6.0.0", 21 | "@capacitor/core": "^6.0.0", 22 | "@capacitor/docgen": "^0.2.1", 23 | "@capacitor/ios": "^6.0.0", 24 | "@ionic/prettier-config": "^2.0.0", 25 | "@types/gapi": "0.0.42", 26 | "@types/gapi.auth2": "0.0.56", 27 | "prettier": "^2.7.1", 28 | "typescript": "^4.7.4" 29 | }, 30 | "peerDependencies": { 31 | "@capacitor/core": "^6.0.0" 32 | }, 33 | "files": [ 34 | "dist/", 35 | "ios/", 36 | "android/", 37 | "!android/src/androidTest", 38 | "!android/src/test", 39 | "CodetrixStudioCapacitorGoogleAuth.podspec" 40 | ], 41 | "keywords": [ 42 | "capacitor", 43 | "plugin", 44 | "native", 45 | "google", 46 | "auth", 47 | "firebase", 48 | "angular", 49 | "vue", 50 | "react", 51 | "ionic" 52 | ], 53 | "capacitor": { 54 | "ios": { 55 | "src": "ios" 56 | }, 57 | "android": { 58 | "src": "android" 59 | } 60 | }, 61 | "repository": { 62 | "type": "git", 63 | "url": "https://github.com/CodetrixStudio/CapacitorGoogleAuth" 64 | }, 65 | "bugs": { 66 | "url": "https://github.com/CodetrixStudio/CapacitorGoogleAuth/issues" 67 | }, 68 | "prettier": "@ionic/prettier-config" 69 | } 70 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import nodeResolve from 'rollup-plugin-node-resolve'; 2 | 3 | export default { 4 | input: 'dist/esm/index.js', 5 | output: { 6 | file: 'dist/plugin.js', 7 | format: 'iife', 8 | name: 'capacitorPlugin', 9 | sourcemap: true, 10 | }, 11 | plugins: [nodeResolve()], 12 | }; 13 | -------------------------------------------------------------------------------- /src/definitions.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '@capacitor/cli' { 4 | export interface PluginsConfig { 5 | GoogleAuth: GoogleAuthPluginOptions; 6 | } 7 | } 8 | 9 | export interface User { 10 | /** 11 | * The unique identifier for the user. 12 | */ 13 | id: string; 14 | 15 | /** 16 | * The email address associated with the user. 17 | */ 18 | email: string; 19 | 20 | /** 21 | * The user's full name. 22 | */ 23 | name: string; 24 | 25 | /** 26 | * The family name (last name) of the user. 27 | */ 28 | familyName: string; 29 | 30 | /** 31 | * The given name (first name) of the user. 32 | */ 33 | givenName: string; 34 | 35 | /** 36 | * The URL of the user's profile picture. 37 | */ 38 | imageUrl: string; 39 | 40 | /** 41 | * The server authentication code. 42 | */ 43 | serverAuthCode: string; 44 | 45 | /** 46 | * The authentication details including access, refresh and ID tokens. 47 | */ 48 | authentication: Authentication; 49 | } 50 | 51 | export interface Authentication { 52 | /** 53 | * The access token obtained during authentication. 54 | */ 55 | accessToken: string; 56 | 57 | /** 58 | * The ID token obtained during authentication. 59 | */ 60 | idToken: string; 61 | 62 | /** 63 | * The refresh token. 64 | * @warning This property is applicable only for mobile platforms (iOS and Android). 65 | */ 66 | refreshToken?: string; 67 | } 68 | 69 | export interface GoogleAuthPluginOptions { 70 | /** 71 | * The default app's client ID, found and created in the Google Developers Console. 72 | * common for Android or iOS 73 | * @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com 74 | * @since 3.1.0 75 | */ 76 | clientId?: string; 77 | 78 | /** 79 | * Specific client ID key for iOS 80 | * @since 3.1.0 81 | */ 82 | iosClientId?: string; 83 | 84 | /** 85 | * Specific client ID key for Android 86 | * @since 3.1.0 87 | */ 88 | androidClientId?: string; 89 | 90 | /** 91 | * Specifies the default scopes required for accessing Google APIs. 92 | * @example ["profile", "email"] 93 | * @default ["email", "profile", "openid"] 94 | * @see [Google OAuth2 Scopes](https://developers.google.com/identity/protocols/oauth2/scopes) 95 | */ 96 | scopes?: string[]; 97 | 98 | /** 99 | * This is used for offline access and server side handling 100 | * @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com 101 | * @default false 102 | */ 103 | serverClientId?: string; 104 | 105 | /** 106 | * Force user to select email address to regenerate AuthCode used to get a valid refreshtoken (work on iOS and Android) 107 | * @default false 108 | */ 109 | forceCodeForRefreshToken?: boolean; 110 | } 111 | 112 | export interface InitOptions { 113 | /** 114 | * The app's client ID, found and created in the Google Developers Console. 115 | * Common for Android or iOS. 116 | * The default is defined in the configuration. 117 | * @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com 118 | * @since 3.1.0 119 | */ 120 | clientId?: string; 121 | 122 | /** 123 | * Specifies the scopes required for accessing Google APIs 124 | * The default is defined in the configuration. 125 | * @example ["profile", "email"] 126 | * @see [Google OAuth2 Scopes](https://developers.google.com/identity/protocols/oauth2/scopes) 127 | */ 128 | scopes?: string[]; 129 | 130 | /** 131 | * Set if your application needs to refresh access tokens when the user is not present at the browser. 132 | * In response use `serverAuthCode` key 133 | * 134 | * @default false 135 | * @since 3.1.0 136 | * */ 137 | grantOfflineAccess?: boolean; 138 | } 139 | 140 | export interface GoogleAuthPlugin { 141 | /** 142 | * Initializes the GoogleAuthPlugin, loading the gapi library and setting up the plugin. 143 | * @param options - Optional initialization options. 144 | * @since 3.1.0 145 | */ 146 | initialize(options?: InitOptions): Promise; 147 | 148 | /** 149 | * Initiates the sign-in process and returns a Promise that resolves with the user information. 150 | */ 151 | signIn(): Promise; 152 | 153 | /** 154 | * Refreshes the authentication token and returns a Promise that resolves with the updated authentication details. 155 | */ 156 | refresh(): Promise; 157 | 158 | /** 159 | * Signs out the user and returns a Promise. 160 | */ 161 | signOut(): Promise; 162 | } 163 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { registerPlugin } from '@capacitor/core'; 2 | import type { GoogleAuthPlugin } from './definitions'; 3 | 4 | const GoogleAuth = registerPlugin('GoogleAuth', { 5 | web: () => import('./web').then((m) => new m.GoogleAuthWeb()), 6 | }); 7 | 8 | export * from './definitions'; 9 | export { GoogleAuth }; 10 | -------------------------------------------------------------------------------- /src/web.ts: -------------------------------------------------------------------------------- 1 | import { WebPlugin } from '@capacitor/core'; 2 | import { GoogleAuthPlugin, InitOptions, User } from './definitions'; 3 | 4 | export class GoogleAuthWeb extends WebPlugin implements GoogleAuthPlugin { 5 | gapiLoaded: Promise; 6 | options: InitOptions; 7 | 8 | constructor() { 9 | super(); 10 | } 11 | 12 | loadScript() { 13 | if (typeof document === 'undefined') { 14 | return; 15 | } 16 | 17 | const scriptId = 'gapi'; 18 | const scriptEl = document?.getElementById(scriptId); 19 | 20 | if (scriptEl) { 21 | return; 22 | } 23 | 24 | const head = document.getElementsByTagName('head')[0]; 25 | const script = document.createElement('script'); 26 | 27 | script.type = 'text/javascript'; 28 | script.defer = true; 29 | script.async = true; 30 | script.id = scriptId; 31 | script.onload = this.platformJsLoaded.bind(this); 32 | script.src = 'https://apis.google.com/js/platform.js'; 33 | head.appendChild(script); 34 | } 35 | 36 | initialize( 37 | _options: Partial = { 38 | clientId: '', 39 | scopes: [], 40 | grantOfflineAccess: false, 41 | } 42 | ): Promise { 43 | if (typeof window === 'undefined') { 44 | return; 45 | } 46 | 47 | const metaClientId = (document.getElementsByName('google-signin-client_id')[0] as any)?.content; 48 | const clientId = _options.clientId || metaClientId || ''; 49 | 50 | if (!clientId) { 51 | console.warn('GoogleAuthPlugin - clientId is empty'); 52 | } 53 | 54 | this.options = { 55 | clientId, 56 | grantOfflineAccess: _options.grantOfflineAccess ?? false, 57 | scopes: _options.scopes || [], 58 | }; 59 | 60 | this.gapiLoaded = new Promise((resolve) => { 61 | // HACK: Relying on window object, can't get property in gapi.load callback 62 | (window as any).gapiResolve = resolve; 63 | this.loadScript(); 64 | }); 65 | 66 | this.addUserChangeListener(); 67 | return this.gapiLoaded; 68 | } 69 | 70 | platformJsLoaded() { 71 | gapi.load('auth2', () => { 72 | // https://github.com/CodetrixStudio/CapacitorGoogleAuth/issues/202#issuecomment-1147393785 73 | const clientConfig: gapi.auth2.ClientConfig & { plugin_name: string } = { 74 | client_id: this.options.clientId, 75 | plugin_name: 'CodetrixStudioCapacitorGoogleAuth', 76 | }; 77 | 78 | if (this.options.scopes.length) { 79 | clientConfig.scope = this.options.scopes.join(' '); 80 | } 81 | 82 | gapi.auth2.init(clientConfig); 83 | (window as any).gapiResolve(); 84 | }); 85 | } 86 | 87 | async signIn() { 88 | return new Promise(async (resolve, reject) => { 89 | try { 90 | let serverAuthCode: string; 91 | const needsOfflineAccess = this.options.grantOfflineAccess ?? false; 92 | 93 | if (needsOfflineAccess) { 94 | const offlineAccessResponse = await gapi.auth2.getAuthInstance().grantOfflineAccess(); 95 | serverAuthCode = offlineAccessResponse.code; 96 | } else { 97 | await gapi.auth2.getAuthInstance().signIn(); 98 | } 99 | 100 | const googleUser = gapi.auth2.getAuthInstance().currentUser.get(); 101 | 102 | if (needsOfflineAccess) { 103 | // HACK: AuthResponse is null if we don't do this when using grantOfflineAccess 104 | await googleUser.reloadAuthResponse(); 105 | } 106 | 107 | const user = this.getUserFrom(googleUser); 108 | user.serverAuthCode = serverAuthCode; 109 | resolve(user); 110 | } catch (error) { 111 | reject(error); 112 | } 113 | }); 114 | } 115 | 116 | async refresh() { 117 | const authResponse = await gapi.auth2.getAuthInstance().currentUser.get().reloadAuthResponse(); 118 | return { 119 | accessToken: authResponse.access_token, 120 | idToken: authResponse.id_token, 121 | refreshToken: '', 122 | }; 123 | } 124 | 125 | async signOut() { 126 | return gapi.auth2.getAuthInstance().signOut(); 127 | } 128 | 129 | private async addUserChangeListener() { 130 | await this.gapiLoaded; 131 | gapi.auth2.getAuthInstance().currentUser.listen((googleUser) => { 132 | this.notifyListeners('userChange', googleUser.isSignedIn() ? this.getUserFrom(googleUser) : null); 133 | }); 134 | } 135 | 136 | private getUserFrom(googleUser: gapi.auth2.GoogleUser) { 137 | const user = {} as User; 138 | const profile = googleUser.getBasicProfile(); 139 | 140 | user.email = profile.getEmail(); 141 | user.familyName = profile.getFamilyName(); 142 | user.givenName = profile.getGivenName(); 143 | user.id = profile.getId(); 144 | user.imageUrl = profile.getImageUrl(); 145 | user.name = profile.getName(); 146 | 147 | const authResponse = googleUser.getAuthResponse(true); 148 | user.authentication = { 149 | accessToken: authResponse.access_token, 150 | idToken: authResponse.id_token, 151 | refreshToken: '', 152 | }; 153 | 154 | return user; 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "experimentalDecorators": true, 6 | "lib": ["dom", "es2017"], 7 | "module": "ESNext", 8 | "moduleResolution": "node", 9 | "noImplicitAny": true, 10 | "noUnusedLocals": true, 11 | "noUnusedParameters": true, 12 | "outDir": "dist/esm", 13 | "sourceMap": true, 14 | "skipLibCheck": true, 15 | "target": "es2017" 16 | }, 17 | "files": ["src/index.ts"] 18 | } 19 | --------------------------------------------------------------------------------