├── .gitignore ├── .idea ├── codeStyles │ └── Project.xml ├── compiler.xml ├── encodings.xml ├── inspectionProfiles │ └── Project_Default.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── org │ │ └── telegram │ │ └── passport │ │ └── example │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── org │ │ │ └── telegram │ │ │ └── passport │ │ │ └── example │ │ │ └── MainActivity.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── ic_corner_round.xml │ │ ├── ic_corner_straight.xml │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── org │ └── telegram │ └── passport │ └── example │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── telegrampassport ├── .gitignore ├── build.gradle ├── gradle.properties ├── maven-push.gradle ├── proguard-rules.pro └── src └── main ├── AndroidManifest.xml ├── java └── org │ └── telegram │ └── passport │ ├── PassportScope.java │ ├── PassportScopeElement.java │ ├── PassportScopeElementOne.java │ ├── PassportScopeElementOneOfSeveral.java │ ├── ScopeValidationException.java │ ├── TelegramLoginButton.java │ └── TelegramPassport.java └── res ├── drawable ├── telegram_logo.xml └── telegram_logo_large.xml ├── values-ar └── strings.xml ├── values-de └── strings.xml ├── values-es └── strings.xml ├── values-fa └── strings.xml ├── values-fr └── strings.xml ├── values-id └── strings.xml ├── values-it └── strings.xml ├── values-ko └── strings.xml ├── values-ms └── strings.xml ├── values-nl └── strings.xml ├── values-pt-rBR └── strings.xml ├── values-ru └── strings.xml ├── values-uk └── strings.xml ├── values-v21 └── styles.xml └── values ├── attrs.xml ├── strings.xml └── styles.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # IntelliJ 36 | *.iml 37 | .idea/workspace.xml 38 | .idea/tasks.xml 39 | .idea/gradle.xml 40 | .idea/assetWizardSettings.xml 41 | .idea/dictionaries 42 | .idea/libraries 43 | .idea/caches 44 | 45 | # Keystore files 46 | # Uncomment the following line if you do not want to check your keystore files in. 47 | #*.jks 48 | 49 | # External native build folder generated in Android Studio 2.2 and later 50 | .externalNativeBuild 51 | 52 | # Google Services (e.g. APIs or Firebase) 53 | google-services.json 54 | 55 | # Freeline 56 | freeline.py 57 | freeline/ 58 | freeline_project_description.json 59 | 60 | # fastlane 61 | fastlane/report.xml 62 | fastlane/Preview.html 63 | fastlane/screenshots 64 | fastlane/test_output 65 | fastlane/readme.md 66 | 67 | # Maven 68 | target/ 69 | pom.xml.tag 70 | pom.xml.releaseBackup 71 | pom.xml.versionsBackup 72 | pom.xml.next 73 | release.properties 74 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 28 | 29 | 30 | 43 | 53 | 54 | 55 | 56 | 57 | 58 | 60 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Telegram Messenger 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Installing 2 | #### Install from Maven 3 | 4 | Telegram Passport SDK is available from the Maven repository. 5 | Add this line to the dependencies section in your build.gradle: 6 | 7 | compile 'org.telegram:passport:1.1' 8 | and sync your project. 9 | #### Add as a module 10 | Download the library, unzip it and copy the library project to the root of your project directory (the one with settings.gradle and gradle.properties). Then, make the following changes to your Gradle scripts. 11 | 12 | In settings.gradle, add `':telegrampassport'` to includes: 13 | 14 | include ':app', ':telegrampassport' 15 | In the build.gradle file for your app, add this line to the dependencies section: 16 | 17 | compile ':telegrampassport' 18 | and sync your project. 19 | ## Using 20 | #### Add a button 21 | The SDK provides the "Log in with Telegram" button we recommend using for a consistent user experience across different apps. You can either add it from your Java code: 22 | 23 | ```java 24 | TelegramLoginButton telegramButton; 25 | // ... 26 | telegramButton=new TelegramLoginButton(this); 27 | // Optionally you can change the roundness of the button corners 28 | // to better fit your design. 29 | telegramButton.setCornerRoundness(1f); 30 | viewGroupOfSomeSort.addView(telegramButton, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); 31 | ``` 32 | Or from XML: 33 | 34 | ```xml 35 | 39 | ``` 40 | 41 | #### Request authorization 42 | 43 | The button doesn't do anything by itself; you need to set an OnClickListener on it to start the authorization flow (replace the comments with the actual parameters): 44 | 45 | ```java 46 | private static final int TG_PASSPORT_RESULT=352; // this can be any integer less than 0xFFFF 47 | // ... 48 | telegramButton.setOnClickListener(new View.OnClickListener(){ 49 | @Override 50 | public void onClick(View view){ 51 | TelegramPassport.AuthRequest req=new TelegramPassport.AuthRequest(); 52 | req.botID=/* your bot ID here */; 53 | req.publicKey=/* your bot public key here */; 54 | req.nonce=/* a unique payload to pass to the bot server */; 55 | // Request either a passport or an ID card with selfie, a driver license, personal details with 56 | // name as it appears in the documents, address with any address document, and a phone number. 57 | // You could also pass a raw JSON object here if that's what works better for you 58 | // (for example, if you already get it from your server in the correct format). 59 | req.scope=new PassportScope( 60 | new PassportScopeElementOneOfSeveral(PassportScope.PASSPORT, PassportScope.IDENTITY_CARD).withSelfie(), 61 | new PassportScopeElementOne(PassportScope.PERSONAL_DETAILS).withNativeNames(), 62 | PassportScope.DRIVER_LICENSE, 63 | PassportScope.ADDRESS, 64 | PassportScope.ADDRESS_DOCUMENT, 65 | PassportScope.PHONE_NUMBER 66 | ); 67 | TelegramPassport.request(MyActivity.this, req, TG_PASSPORT_RESULT); 68 | }}); 69 | ``` 70 | If you need finer-grained control over the process, `TelegramPassport` class contains a couple more methods: 71 | 72 | - `getAuthIntent(AuthParams)` returns an `Intent` for you to use in `startActivityForResult` if you need to do that in some special way. Be sure to check that there's actually an app to handle this intent before starting it by using `PackageManager` or `intent.resolveActivity`. 73 | - `showAppInstallAlert(Activity)` shows an alert that the user needs to install Telegram in order to continue. This is intended to be used together with the previous method in case when the app isn't installed. 74 | 75 | #### Handle the result 76 | The result is delivered via the `onActivityResult` method in your activity with the request code you passed to `TelegramPassport.request`. Currently, the only meaningful parameter is `resultCode`, which is `RESULT_OK` if the authorization was successful and `RESULT_CANCELED` otherwise. 77 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # IntelliJ 36 | *.iml 37 | .idea/workspace.xml 38 | .idea/tasks.xml 39 | .idea/gradle.xml 40 | .idea/assetWizardSettings.xml 41 | .idea/dictionaries 42 | .idea/libraries 43 | .idea/caches 44 | 45 | # Keystore files 46 | # Uncomment the following line if you do not want to check your keystore files in. 47 | #*.jks 48 | 49 | # External native build folder generated in Android Studio 2.2 and later 50 | .externalNativeBuild 51 | 52 | # Google Services (e.g. APIs or Firebase) 53 | google-services.json 54 | 55 | # Freeline 56 | freeline.py 57 | freeline/ 58 | freeline_project_description.json 59 | 60 | # fastlane 61 | fastlane/report.xml 62 | fastlane/Preview.html 63 | fastlane/screenshots 64 | fastlane/test_output 65 | fastlane/readme.md 66 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | defaultConfig { 6 | applicationId "org.telegram.passport.example" 7 | minSdkVersion 16 8 | targetSdkVersion 28 9 | versionCode 2 10 | versionName "1.1" 11 | } 12 | buildTypes { 13 | release { 14 | minifyEnabled false 15 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 16 | } 17 | } 18 | } 19 | 20 | dependencies { 21 | implementation fileTree(dir: 'libs', include: ['*.jar']) 22 | implementation 'com.android.support:appcompat-v7:28.0.0-rc01' 23 | implementation project(':telegrampassport') 24 | } 25 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/src/androidTest/java/org/telegram/passport/example/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package org.telegram.passport.example; 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(){ 21 | // Context of the app under test. 22 | Context appContext=InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("org.telegram.passport.example", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/java/org/telegram/passport/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package org.telegram.passport.example; 2 | 3 | import android.app.AlertDialog; 4 | import android.content.Intent; 5 | import android.support.annotation.IdRes; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.os.Bundle; 8 | import android.text.TextUtils; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.CheckBox; 12 | import android.widget.CompoundButton; 13 | import android.widget.LinearLayout; 14 | import android.widget.SeekBar; 15 | import android.widget.Toast; 16 | 17 | import org.telegram.passport.PassportScope; 18 | import org.telegram.passport.PassportScopeElementOne; 19 | import org.telegram.passport.PassportScopeElementOneOfSeveral; 20 | import org.telegram.passport.TelegramLoginButton; 21 | import org.telegram.passport.TelegramPassport; 22 | 23 | import java.util.ArrayList; 24 | import java.util.Arrays; 25 | import java.util.List; 26 | import java.util.UUID; 27 | 28 | public class MainActivity extends AppCompatActivity{ 29 | 30 | private TelegramLoginButton loginButton; 31 | private SeekBar cornerRoundnessSlider; 32 | private String payload=UUID.randomUUID().toString(); 33 | 34 | private View.OnClickListener loginClickListener=new View.OnClickListener(){ 35 | @Override 36 | public void onClick(View v){ 37 | TelegramPassport.AuthRequest params=new TelegramPassport.AuthRequest(); 38 | params.botID=443863171; 39 | params.nonce=payload; 40 | params.publicKey="-----BEGIN PUBLIC KEY-----\n"+ 41 | "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzmgKr0fPP4rB/TsNEweC\n"+ 42 | "hoG3ntUxuBTmHsFBW6CpABGdaTmKZSjAI/cTofhBgtRQIOdX0YRGHHHhwyLf49Wv\n"+ 43 | "9l+XexbJOa0lTsJSNMj8Y/9sZbqUl5ur8ZOTM0sxbXC0XKexu1tM9YavH+Lbrobk\n"+ 44 | "jt0+cmo/zEYZWNtLVihnR2IDv+7tSgiDoFWi/koAUdfJ1VMw+hReUaLg3vE9CmPK\n"+ 45 | "tQiTy+NvmrYaBPb75I0Jz3Lrz1+mZSjLKO25iT84RIsxarBDd8iYh2avWkCmvtiR\n"+ 46 | "Lcif8wLxi2QWC1rZoCA3Ip+Hg9J9vxHlzl6xT01WjUStMhfwrUW6QBpur7FJ+aKM\n"+ 47 | "oaMoHieFNCG4qIkWVEHHSsUpLum4SYuEnyNH3tkjbrdldZanCvanGq+TZyX0buRt\n"+ 48 | "4zk7FGcu8iulUkAP/o/WZM0HKinFN/vuzNVA8iqcO/BBhewhzpqmmTMnWmAO8WPP\n"+ 49 | "DJMABRtXJnVuPh1CI5pValzomLJM4/YvnJGppzI1QiHHNA9JtxVmj2xf8jaXa1LJ\n"+ 50 | "WUNJK+RvUWkRUxpWiKQQO9FAyTPLRtDQGN9eUeDR1U0jqRk/gNT8smHGN6I4H+NR\n"+ 51 | "3X3/1lMfcm1dvk654ql8mxjCA54IpTPr/icUMc7cSzyIiQ7Tp9PZTl1gHh281ZWf\n"+ 52 | "P7d2+fuJMlkjtM7oAwf+tI8CAwEAAQ==\n"+ 53 | "-----END PUBLIC KEY-----"; 54 | PassportScope scope=new PassportScope(); 55 | /*ArrayList scope=new ArrayList<>(); 56 | ViewGroup scopeView1=findViewById(R.id.scope1), scopeView2=findViewById(R.id.scope2); 57 | for(int i=0;i(); 72 | if(isChecked(R.id.scope_personal_details)){ 73 | PassportScopeElementOne e=new PassportScopeElementOne(); 74 | e.type=PassportScope.PERSONAL_DETAILS; 75 | e.nativeNames=isChecked(R.id.scope_native_names); 76 | scope.data.add(e); 77 | } 78 | List idList; 79 | if(isChecked(R.id.scope_id_all_of)){ 80 | idList=(List)(List)scope.data; // I don't care 81 | }else{ 82 | PassportScopeElementOneOfSeveral one=new PassportScopeElementOneOfSeveral(); 83 | one.oneOf=new ArrayList<>(); 84 | idList=one.oneOf; 85 | scope.data.add(one); 86 | } 87 | if(isChecked(R.id.scope_passport)){ 88 | PassportScopeElementOne e=new PassportScopeElementOne(); 89 | e.type=PassportScope.PASSPORT; 90 | e.selfie=isChecked(R.id.scope_passport_selfie); 91 | e.translation=isChecked(R.id.scope_passport_translation); 92 | idList.add(e); 93 | } 94 | if(isChecked(R.id.scope_driver_license)){ 95 | PassportScopeElementOne e=new PassportScopeElementOne(); 96 | e.type=PassportScope.DRIVER_LICENSE; 97 | e.selfie=isChecked(R.id.scope_driver_license_selfie); 98 | e.translation=isChecked(R.id.scope_driver_license_translation); 99 | idList.add(e); 100 | } 101 | if(isChecked(R.id.scope_identity_card)){ 102 | PassportScopeElementOne e=new PassportScopeElementOne(); 103 | e.type=PassportScope.IDENTITY_CARD; 104 | e.selfie=isChecked(R.id.scope_identity_card_selfie); 105 | e.translation=isChecked(R.id.scope_identity_card_translation); 106 | idList.add(e); 107 | } 108 | if(isChecked(R.id.scope_internal_passport)){ 109 | PassportScopeElementOne e=new PassportScopeElementOne(); 110 | e.type=PassportScope.INTERNAL_PASSPORT; 111 | e.selfie=isChecked(R.id.scope_internal_passport_selfie); 112 | e.translation=isChecked(R.id.scope_internal_passport_translation); 113 | idList.add(e); 114 | } 115 | 116 | 117 | if(isChecked(R.id.scope_address)){ 118 | PassportScopeElementOne e=new PassportScopeElementOne(); 119 | e.type=PassportScope.ADDRESS; 120 | scope.data.add(e); 121 | } 122 | List addressList; 123 | if(isChecked(R.id.scope_id_all_of)){ 124 | addressList=(List)(List)scope.data; // I don't care 125 | }else{ 126 | PassportScopeElementOneOfSeveral one=new PassportScopeElementOneOfSeveral(); 127 | one.oneOf=new ArrayList<>(); 128 | addressList=one.oneOf; 129 | scope.data.add(one); 130 | } 131 | if(isChecked(R.id.scope_utility_bill)){ 132 | PassportScopeElementOne e=new PassportScopeElementOne(); 133 | e.type=PassportScope.UTILITY_BILL; 134 | e.translation=isChecked(R.id.scope_utility_bill_translation); 135 | addressList.add(e); 136 | } 137 | if(isChecked(R.id.scope_bank_statement)){ 138 | PassportScopeElementOne e=new PassportScopeElementOne(); 139 | e.type=PassportScope.BANK_STATEMENT; 140 | e.translation=isChecked(R.id.scope_bank_statement_translation); 141 | addressList.add(e); 142 | } 143 | if(isChecked(R.id.scope_rental_agreement)){ 144 | PassportScopeElementOne e=new PassportScopeElementOne(); 145 | e.type=PassportScope.RENTAL_AGREEMENT; 146 | e.translation=isChecked(R.id.scope_rental_agreement_translation); 147 | addressList.add(e); 148 | } 149 | if(isChecked(R.id.scope_passport_registration)){ 150 | PassportScopeElementOne e=new PassportScopeElementOne(); 151 | e.type=PassportScope.PASSPORT_REGISTRATION; 152 | e.translation=isChecked(R.id.scope_passport_registration_translation); 153 | addressList.add(e); 154 | } 155 | if(isChecked(R.id.scope_temporary_registration)){ 156 | PassportScopeElementOne e=new PassportScopeElementOne(); 157 | e.type=PassportScope.TEMPORARY_REGISTRATION; 158 | e.translation=isChecked(R.id.scope_temporary_registration_translation); 159 | addressList.add(e); 160 | } 161 | 162 | if(isChecked(R.id.scope_phone)){ 163 | PassportScopeElementOne e=new PassportScopeElementOne(); 164 | e.type=PassportScope.PHONE_NUMBER; 165 | scope.data.add(e); 166 | } 167 | if(isChecked(R.id.scope_email)){ 168 | PassportScopeElementOne e=new PassportScopeElementOne(); 169 | e.type=PassportScope.EMAIL; 170 | scope.data.add(e); 171 | } 172 | 173 | //params.scope=scope; 174 | params.scope=new PassportScope( 175 | new PassportScopeElementOneOfSeveral(PassportScope.PASSPORT, PassportScope.IDENTITY_CARD).withSelfie(), 176 | new PassportScopeElementOne(PassportScope.PERSONAL_DETAILS).withNativeNames(), 177 | PassportScope.DRIVER_LICENSE, 178 | PassportScope.ADDRESS, 179 | PassportScope.ADDRESS_DOCUMENT, 180 | PassportScope.PHONE_NUMBER 181 | ); 182 | TelegramPassport.request(MainActivity.this, params, 105); 183 | } 184 | }; 185 | 186 | private View.OnLongClickListener loginLongClickListener=new View.OnLongClickListener(){ 187 | @Override 188 | public boolean onLongClick(View v){ 189 | TelegramPassport.showAppInstallAlert(MainActivity.this); 190 | return true; 191 | } 192 | }; 193 | 194 | @Override 195 | protected void onCreate(Bundle savedInstanceState){ 196 | super.onCreate(savedInstanceState); 197 | if(savedInstanceState!=null) 198 | payload=savedInstanceState.getString("payload"); 199 | setContentView(R.layout.activity_main); 200 | 201 | loginButton=findViewById(R.id.login_button); 202 | loginButton.setOnClickListener(loginClickListener); 203 | loginButton.setOnLongClickListener(loginLongClickListener); 204 | 205 | cornerRoundnessSlider=findViewById(R.id.corner_roundness_slider); 206 | cornerRoundnessSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){ 207 | @Override 208 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser){ 209 | loginButton.setCornerRoundness(progress/(float)seekBar.getMax()); 210 | } 211 | 212 | @Override 213 | public void onStartTrackingTouch(SeekBar seekBar){ 214 | 215 | } 216 | 217 | @Override 218 | public void onStopTrackingTouch(SeekBar seekBar){ 219 | 220 | } 221 | }); 222 | } 223 | 224 | @Override 225 | protected void onSaveInstanceState(Bundle outState){ 226 | super.onSaveInstanceState(outState); 227 | outState.putSerializable("payload", payload); 228 | } 229 | 230 | @Override 231 | protected void onActivityResult(int requestCode, int resultCode, Intent data){ 232 | if(requestCode==105){ 233 | if(resultCode==RESULT_OK){ 234 | Toast.makeText(this, R.string.login_successful, Toast.LENGTH_SHORT).show(); 235 | }else if(resultCode==TelegramPassport.RESULT_ERROR){ 236 | new AlertDialog.Builder(this) 237 | .setTitle(R.string.error) 238 | .setMessage(data.getStringExtra("error")) 239 | .setPositiveButton(R.string.ok, null) 240 | .show(); 241 | }else{ 242 | Toast.makeText(this, R.string.login_canceled, Toast.LENGTH_SHORT).show(); 243 | } 244 | } 245 | } 246 | 247 | private boolean isChecked(@IdRes int id){ 248 | return ((CompoundButton)findViewById(id)).isChecked(); 249 | } 250 | } 251 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_corner_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_corner_straight.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 11 | 16 | 21 | 26 | 31 | 36 | 41 | 46 | 51 | 56 | 61 | 66 | 71 | 76 | 81 | 86 | 91 | 96 | 101 | 106 | 111 | 116 | 121 | 126 | 131 | 136 | 141 | 146 | 151 | 156 | 161 | 166 | 171 | 172 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 17 | 21 | 29 | 30 | 31 | 39 | 46 | 47 | 49 | 57 | 66 | 67 | 68 | 74 | 77 | 80 | 81 | 82 | 88 | 91 | 94 | 95 | 96 | 102 | 105 | 108 | 109 | 110 | 115 | 118 | 121 | 122 | 123 | 125 | 133 | 138 | 139 | 140 | 141 | 149 | 150 | 151 | 159 | 160 | 161 | 167 | 168 | 175 | 178 | 179 | 180 | 187 | 190 | 191 | 192 | 199 | 202 | 203 | 204 | 210 | 213 | 214 | 215 | 221 | 224 | 225 | 226 | 228 | 236 | 241 | 242 | 243 | 251 | 252 | 258 | 264 | 265 | 266 | 267 | 273 | 274 | 275 | 278 | 279 | 288 | 289 | 298 | 299 | 308 | 309 | 322 | 323 | 324 | 331 | 332 | 333 | 334 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TelegramMessenger/TGPassportAndroidSDK/f124a865286e5ebfed7c90c68ec3930305a9e521/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TelegramMessenger/TGPassportAndroidSDK/f124a865286e5ebfed7c90c68ec3930305a9e521/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TelegramMessenger/TGPassportAndroidSDK/f124a865286e5ebfed7c90c68ec3930305a9e521/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TelegramMessenger/TGPassportAndroidSDK/f124a865286e5ebfed7c90c68ec3930305a9e521/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TelegramMessenger/TGPassportAndroidSDK/f124a865286e5ebfed7c90c68ec3930305a9e521/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TelegramMessenger/TGPassportAndroidSDK/f124a865286e5ebfed7c90c68ec3930305a9e521/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TelegramMessenger/TGPassportAndroidSDK/f124a865286e5ebfed7c90c68ec3930305a9e521/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TelegramMessenger/TGPassportAndroidSDK/f124a865286e5ebfed7c90c68ec3930305a9e521/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TelegramMessenger/TGPassportAndroidSDK/f124a865286e5ebfed7c90c68ec3930305a9e521/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TelegramMessenger/TGPassportAndroidSDK/f124a865286e5ebfed7c90c68ec3930305a9e521/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #527da3 4 | #426482 5 | #33a8e6 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Telegram Passport Example 3 | Error 4 | OK 5 | Login canceled 6 | Button Style 7 | Logged in successfully 8 | Name & Identity 9 | Address 10 | Selfie 11 | Translation 12 | Personal details 13 | Include name in the original language 14 | Passport 15 | Driver License 16 | Identity Card 17 | Internal Passport 18 | One of these 19 | All of these 20 | Utility Bill 21 | Bank Statement 22 | Rental Agreement 23 | Registration in Internal Passport 24 | Temporary Registration 25 | Contacts 26 | Email 27 | Phone Number 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/org/telegram/passport/example/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package org.telegram.passport.example; 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(){ 15 | assertEquals(4, 2+2); 16 | } 17 | } -------------------------------------------------------------------------------- /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.1.1' 11 | 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 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | 15 | VERSION_NAME=1.1 16 | VERSION_CODE=2 17 | GROUP=org.telegram 18 | 19 | POM_DESCRIPTION=Telegram Passport SDK for Android 20 | POM_URL=https://github.com/TelegramMessenger/TGPassportAndroidSDK 21 | POM_SCM_URL=https://github.com/TelegramMessenger/TGPassportAndroidSDK 22 | POM_SCM_CONNECTION=scm:git@github.com:TelegramMessenger/TGPassportAndroidSDK.git 23 | POM_SCM_DEV_CONNECTION=scm:git@github.com:TelegramMessenger/TGPassportAndroidSDK.git 24 | POM_LICENCE_NAME=MIT License 25 | POM_LICENCE_URL=http://www.opensource.org/licenses/mit-license.php 26 | POM_LICENCE_DIST=repo 27 | POM_DEVELOPER_ID=grishka 28 | POM_DEVELOPER_NAME=Gregory Klyushnikov -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TelegramMessenger/TGPassportAndroidSDK/f124a865286e5ebfed7c90c68ec3930305a9e521/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Apr 10 13:41:25 MSK 2018 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-4.4-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':telegrampassport' 2 | -------------------------------------------------------------------------------- /telegrampassport/.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # IntelliJ 36 | *.iml 37 | .idea/workspace.xml 38 | .idea/tasks.xml 39 | .idea/gradle.xml 40 | .idea/assetWizardSettings.xml 41 | .idea/dictionaries 42 | .idea/libraries 43 | .idea/caches 44 | 45 | # Keystore files 46 | # Uncomment the following line if you do not want to check your keystore files in. 47 | #*.jks 48 | 49 | # External native build folder generated in Android Studio 2.2 and later 50 | .externalNativeBuild 51 | 52 | # Google Services (e.g. APIs or Firebase) 53 | google-services.json 54 | 55 | # Freeline 56 | freeline.py 57 | freeline/ 58 | freeline_project_description.json 59 | 60 | # fastlane 61 | fastlane/report.xml 62 | fastlane/Preview.html 63 | fastlane/screenshots 64 | fastlane/test_output 65 | fastlane/readme.md 66 | -------------------------------------------------------------------------------- /telegrampassport/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply from: 'maven-push.gradle' 3 | 4 | android { 5 | compileSdkVersion 28 6 | 7 | 8 | 9 | defaultConfig { 10 | minSdkVersion 16 11 | targetSdkVersion 28 12 | versionCode 2 13 | versionName "1.1" 14 | } 15 | 16 | buildTypes { 17 | release { 18 | minifyEnabled false 19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 20 | } 21 | } 22 | 23 | } 24 | 25 | dependencies { 26 | implementation fileTree(dir: 'libs', include: ['*.jar']) 27 | } 28 | -------------------------------------------------------------------------------- /telegrampassport/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=TelegramPassportSDK 2 | POM_ARTIFACT_ID=passport 3 | POM_PACKAGING=aar -------------------------------------------------------------------------------- /telegrampassport/maven-push.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Chris Banes 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | apply plugin: 'maven' 18 | apply plugin: 'signing' 19 | 20 | def isReleaseBuild() { 21 | return VERSION_NAME.contains("SNAPSHOT") == false 22 | } 23 | 24 | def getReleaseRepositoryUrl() { 25 | return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL 26 | : "https://oss.sonatype.org/service/local/staging/deploy/maven2/" 27 | } 28 | 29 | def getSnapshotRepositoryUrl() { 30 | return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL 31 | : "https://oss.sonatype.org/content/repositories/snapshots/" 32 | } 33 | 34 | def getRepositoryUsername() { 35 | return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : "" 36 | } 37 | 38 | def getRepositoryPassword() { 39 | return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : "" 40 | } 41 | 42 | afterEvaluate { project -> 43 | uploadArchives { 44 | repositories { 45 | mavenDeployer { 46 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } 47 | 48 | pom.groupId = GROUP 49 | pom.artifactId = POM_ARTIFACT_ID 50 | pom.version = VERSION_NAME 51 | 52 | repository(url: getReleaseRepositoryUrl()) { 53 | authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) 54 | } 55 | snapshotRepository(url: getSnapshotRepositoryUrl()) { 56 | authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) 57 | } 58 | 59 | pom.project { 60 | name POM_NAME 61 | packaging POM_PACKAGING 62 | description POM_DESCRIPTION 63 | url POM_URL 64 | 65 | scm { 66 | url POM_SCM_URL 67 | connection POM_SCM_CONNECTION 68 | developerConnection POM_SCM_DEV_CONNECTION 69 | } 70 | 71 | licenses { 72 | license { 73 | name POM_LICENCE_NAME 74 | url POM_LICENCE_URL 75 | distribution POM_LICENCE_DIST 76 | } 77 | } 78 | 79 | developers { 80 | developer { 81 | id POM_DEVELOPER_ID 82 | name POM_DEVELOPER_NAME 83 | } 84 | } 85 | } 86 | } 87 | } 88 | } 89 | 90 | signing { 91 | required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") } 92 | sign configurations.archives 93 | } 94 | 95 | //task androidJavadocs(type: Javadoc) { 96 | //source = android.sourceSets.main.allJava 97 | //} 98 | 99 | //task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) { 100 | //classifier = 'javadoc' 101 | //from androidJavadocs.destinationDir 102 | //} 103 | 104 | task androidSourcesJar(type: Jar) { 105 | classifier = 'sources' 106 | from android.sourceSets.main.java.sourceFiles 107 | } 108 | 109 | artifacts { 110 | archives androidSourcesJar 111 | } 112 | } -------------------------------------------------------------------------------- /telegrampassport/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 | -------------------------------------------------------------------------------- /telegrampassport/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /telegrampassport/src/main/java/org/telegram/passport/PassportScope.java: -------------------------------------------------------------------------------- 1 | package org.telegram.passport; 2 | 3 | import org.json.JSONArray; 4 | import org.json.JSONException; 5 | import org.json.JSONObject; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | /** 12 | * This object represents the data to be requested. 13 | */ 14 | public class PassportScope{ 15 | 16 | /** 17 | * Value for {@link PassportScopeElementOne#type}: request personal details 18 | */ 19 | public static final String PERSONAL_DETAILS="personal_details"; 20 | /** 21 | * Value for {@link PassportScopeElementOne#type}: request passport as one of identity documents 22 | */ 23 | public static final String PASSPORT="passport"; 24 | /** 25 | * Value for {@link PassportScopeElementOne#type}: request internal passport as one of identity documents 26 | */ 27 | public static final String INTERNAL_PASSPORT="internal_passport"; 28 | /** 29 | * Value for {@link PassportScopeElementOne#type}: request driver license as one of identity documents 30 | */ 31 | public static final String DRIVER_LICENSE="driver_license"; 32 | /** 33 | * Value for {@link PassportScopeElementOne#type}: request ID card as one of identity documents 34 | */ 35 | public static final String IDENTITY_CARD="identity_card"; 36 | /** 37 | * Value for {@link PassportScopeElementOne#type}: request any identity document. Same as [{@link #PASSPORT}, {@link #DRIVER_LICENSE}, {@link #IDENTITY_CARD}] 38 | */ 39 | public static final String ID_DOCUMENT="id_document"; 40 | /** 41 | * Value for {@link PassportScopeElementOne#type}: request residential address 42 | */ 43 | public static final String ADDRESS="address"; 44 | /** 45 | * Value for {@link PassportScopeElementOne#type}: request utility bill as one of proofs of address 46 | */ 47 | public static final String UTILITY_BILL="utility_bill"; 48 | /** 49 | * Value for {@link PassportScopeElementOne#type}: request bank statement as one of proofs of address 50 | */ 51 | public static final String BANK_STATEMENT="bank_statement"; 52 | /** 53 | * Value for {@link PassportScopeElementOne#type}: request rental agreement as one of proofs of address 54 | */ 55 | public static final String RENTAL_AGREEMENT="rental_agreement"; 56 | /** 57 | * Value for {@link PassportScopeElementOne#type}: request registration in the internal passport as one of proofs of address 58 | */ 59 | public static final String PASSPORT_REGISTRATION="passport_registration"; 60 | /** 61 | * Value for {@link PassportScopeElementOne#type}: request temporary registration as one of proofs of address 62 | */ 63 | public static final String TEMPORARY_REGISTRATION="temporary_registration"; 64 | /** 65 | * Value for {@link PassportScopeElementOne#type}: request any proof of address. Same as [{@link #UTILITY_BILL}, {@link #BANK_STATEMENT}, {@link #RENTAL_AGREEMENT}] 66 | */ 67 | public static final String ADDRESS_DOCUMENT="address_document"; 68 | /** 69 | * Value for {@link PassportScopeElementOne#type}: request phone number 70 | */ 71 | public static final String PHONE_NUMBER="phone_number"; 72 | /** 73 | * Value for {@link PassportScopeElementOne#type}: request email address 74 | */ 75 | public static final String EMAIL="email"; 76 | 77 | /** 78 | * Scope version, must be 1 79 | */ 80 | public int v=1; 81 | /** 82 | * List of requested elements, each type may be used only once in the entire array of {@link PassportScopeElement} objects 83 | */ 84 | public List data; 85 | private JSONObject json; 86 | 87 | /** 88 | * Construct a new PassportScope and initialize its {@link PassportScope#data} field. 89 | * @param data list of requested elements 90 | */ 91 | public PassportScope(List data){ 92 | this.data=data; 93 | } 94 | 95 | /** 96 | * Construct a new PassportScope and initialize its {@link PassportScope#data} field. 97 | * @param data list of requested elements 98 | */ 99 | public PassportScope(PassportScopeElement... data){ 100 | this.data=Arrays.asList(data); 101 | } 102 | 103 | /** 104 | * Construct a new PassportScope with a JSON object to be passed directly to the Telegram app. 105 | * The JSON object must contain fields data and v. 106 | * @param json JSON object to set 107 | * @throws ScopeValidationException if the object doesn't contain the required fields 108 | */ 109 | public PassportScope(JSONObject json) throws ScopeValidationException{ 110 | if(!json.has("data") || !json.has("v")) 111 | throw new ScopeValidationException("JSON object must contain v and data fields"); 112 | this.json=json; 113 | } 114 | 115 | /** 116 | * Construct a new PassportScope and initialize its {@link PassportScope#data} field. 117 | * @param data {@link String}s and {@link PassportScopeElement}s with data to be requested. 118 | * {@link String}s can be used to simplify the code; they will be converted to {@link PassportScopeElementOne} with all flags set to false. 119 | * Null elements will be skipped. 120 | */ 121 | public PassportScope(Object... data){ 122 | this.data=new ArrayList<>(); 123 | for(Object o:data){ 124 | if(o==null) 125 | continue; 126 | if(o instanceof PassportScopeElement) 127 | this.data.add((PassportScopeElement) o); 128 | else if(o instanceof String) 129 | this.data.add(new PassportScopeElementOne((String)o)); 130 | else 131 | throw new IllegalArgumentException("This constructor only accepts PassportScopeElement and String, found "+o.getClass().getSimpleName()); 132 | } 133 | } 134 | 135 | public PassportScope(){ 136 | 137 | } 138 | 139 | public JSONObject toJSON(){ 140 | if(json!=null) 141 | return json; 142 | try{ 143 | JSONObject s=new JSONObject(); 144 | s.put("v", v); 145 | JSONArray d=new JSONArray(); 146 | for(PassportScopeElement el:data){ 147 | Object j=el.toJSON(); 148 | if(j!=null) 149 | d.put(j); 150 | } 151 | s.put("data", d); 152 | return s; 153 | }catch(JSONException ignore){} 154 | return null; 155 | } 156 | 157 | public void validate() throws ScopeValidationException{ 158 | if(json!=null) 159 | return; 160 | for(PassportScopeElement el:data) 161 | el.validate(); 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /telegrampassport/src/main/java/org/telegram/passport/PassportScopeElement.java: -------------------------------------------------------------------------------- 1 | package org.telegram.passport; 2 | 3 | import org.json.JSONObject; 4 | 5 | public abstract class PassportScopeElement{ 6 | /*package*/ abstract Object toJSON(); 7 | /*packags*/ abstract void validate() throws ScopeValidationException; 8 | } 9 | -------------------------------------------------------------------------------- /telegrampassport/src/main/java/org/telegram/passport/PassportScopeElementOne.java: -------------------------------------------------------------------------------- 1 | package org.telegram.passport; 2 | 3 | import org.json.JSONException; 4 | import org.json.JSONObject; 5 | 6 | import java.util.Arrays; 7 | 8 | /** 9 | * This object represents one particular element that must be provided. 10 | */ 11 | public class PassportScopeElementOne extends PassportScopeElement{ 12 | /** 13 | * Element type. One of {@link PassportScope#PERSONAL_DETAILS}, {@link PassportScope#PASSPORT}, {@link PassportScope#DRIVER_LICENSE}, {@link PassportScope#IDENTITY_CARD}, {@link PassportScope#INTERNAL_PASSPORT}, {@link PassportScope#ADDRESS}, {@link PassportScope#UTILITY_BILL}, 14 | * {@link PassportScope#BANK_STATEMENT}, {@link PassportScope#RENTAL_AGREEMENT}, {@link PassportScope#PASSPORT_REGISTRATION}, {@link PassportScope#TEMPORARY_REGISTRATION}, {@link PassportScope#PHONE_NUMBER}, {@link PassportScope#EMAIL} 15 | *

16 | * You can also use the special type {@link PassportScope#ID_DOCUMENT} as an alias for one of {@link PassportScope#PASSPORT}, {@link PassportScope#DRIVER_LICENSE}, {@link PassportScope#IDENTITY_CARD} 17 | * and the special type {@link PassportScope#ADDRESS_DOCUMENT} as an alias for one of {@link PassportScope#UTILITY_BILL}, {@link PassportScope#BANK_STATEMENT}, {@link PassportScope#RENTAL_AGREEMENT}. 18 | */ 19 | public String type; 20 | /** 21 | * Optional. Use this parameter if you want to request a selfie with the document as well. Available for {@link PassportScope#PASSPORT}, {@link PassportScope#DRIVER_LICENSE}, 22 | * {@link PassportScope#IDENTITY_CARD} and {@link PassportScope#INTERNAL_PASSPORT} 23 | */ 24 | public boolean selfie; 25 | /** 26 | * Optional. Use this parameter if you want to request a translation of the document as well. Available for {@link PassportScope#PASSPORT}, {@link PassportScope#DRIVER_LICENSE}, 27 | * {@link PassportScope#IDENTITY_CARD}, {@link PassportScope#INTERNAL_PASSPORT}, {@link PassportScope#UTILITY_BILL}, {@link PassportScope#BANK_STATEMENT}, {@link PassportScope#RENTAL_AGREEMENT}, {@link PassportScope#PASSPORT_REGISTRATION} and {@link PassportScope#TEMPORARY_REGISTRATION} 28 | */ 29 | public boolean translation; 30 | /** 31 | * Optional. Use this parameter to request the first, last and middle name of the user in the language of the country that issued the document. 32 | * Available for {@link PassportScope#PERSONAL_DETAILS} 33 | */ 34 | public boolean nativeNames; 35 | 36 | public PassportScopeElementOne(String type){ 37 | this.type=type; 38 | } 39 | 40 | public PassportScopeElementOne(){ 41 | 42 | } 43 | 44 | @Override 45 | Object toJSON(){ 46 | if(!selfie && !translation && !nativeNames) 47 | return type; 48 | try{ 49 | JSONObject o=new JSONObject(); 50 | o.put("type", type); 51 | if(selfie) 52 | o.put("selfie", true); 53 | if(translation) 54 | o.put("translation", true); 55 | if(nativeNames) 56 | o.put("native_names", true); 57 | return o; 58 | }catch(JSONException ignore){} 59 | return null; 60 | } 61 | 62 | @Override 63 | void validate() throws ScopeValidationException{ 64 | if(nativeNames && !PassportScope.PERSONAL_DETAILS.equals(type)) 65 | throw new ScopeValidationException("nativeNames can only be used with personal_details"); 66 | if(selfie && Arrays.asList(PassportScope.UTILITY_BILL, PassportScope.BANK_STATEMENT, PassportScope.RENTAL_AGREEMENT, PassportScope.PASSPORT_REGISTRATION, PassportScope.TEMPORARY_REGISTRATION).contains(type)) 67 | throw new ScopeValidationException("selfie can only be used with identity documents"); 68 | if(Arrays.asList(PassportScope.PHONE_NUMBER, PassportScope.EMAIL, PassportScope.ADDRESS, PassportScope.PERSONAL_DETAILS).contains(type)){ 69 | if(selfie) 70 | throw new ScopeValidationException("selfie can only be used with identity documents"); 71 | if(translation) 72 | throw new ScopeValidationException("translation can only be used with documents"); 73 | if(nativeNames && !PassportScope.PERSONAL_DETAILS.equals(type)) 74 | throw new ScopeValidationException("nativeNames can only be used with personal_details"); 75 | } 76 | } 77 | 78 | /** 79 | * Request selfie 80 | * @see PassportScopeElementOne#selfie 81 | * @return this object for chaining 82 | */ 83 | public PassportScopeElementOne withSelfie(){ 84 | selfie=true; 85 | return this; 86 | } 87 | 88 | /** 89 | * Request translation 90 | * @see PassportScopeElementOne#translation 91 | * @return this object for chaining 92 | */ 93 | public PassportScopeElementOne withTranslation(){ 94 | translation=true; 95 | return this; 96 | } 97 | 98 | /** 99 | * Request native names 100 | * @see PassportScopeElementOne#nativeNames 101 | * @return this object for method chaining 102 | */ 103 | public PassportScopeElementOne withNativeNames(){ 104 | nativeNames=true; 105 | return this; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /telegrampassport/src/main/java/org/telegram/passport/PassportScopeElementOneOfSeveral.java: -------------------------------------------------------------------------------- 1 | package org.telegram.passport; 2 | 3 | import org.json.JSONArray; 4 | import org.json.JSONException; 5 | import org.json.JSONObject; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | /** 12 | * This object represents several elements one of which must be provided. 13 | */ 14 | public class PassportScopeElementOneOfSeveral extends PassportScopeElement{ 15 | /** 16 | * List of elements one of which must be provided; must contain either several of 17 | * {@link PassportScope#PASSPORT}, {@link PassportScope#DRIVER_LICENSE}, {@link PassportScope#IDENTITY_CARD}, {@link PassportScope#INTERNAL_PASSPORT} or 18 | * several of {@link PassportScope#UTILITY_BILL}, {@link PassportScope#BANK_STATEMENT}, {@link PassportScope#RENTAL_AGREEMENT}, {@link PassportScope#PASSPORT_REGISTRATION}, {@link PassportScope#TEMPORARY_REGISTRATION} 19 | */ 20 | public List oneOf; 21 | /** 22 | * Optional. Use this parameter if you want to request a selfie with the document from this list that the user chooses to upload. 23 | */ 24 | public boolean selfie; 25 | /** 26 | * Optional. Use this parameter if you want to request a translation of the document from this list that the user chooses to upload. 27 | */ 28 | public boolean translation; 29 | 30 | public PassportScopeElementOneOfSeveral(List oneOf){ 31 | this.oneOf=oneOf; 32 | } 33 | 34 | public PassportScopeElementOneOfSeveral(PassportScopeElementOne... oneOf){ 35 | this.oneOf=Arrays.asList(oneOf); 36 | } 37 | 38 | public PassportScopeElementOneOfSeveral(String... oneOf){ 39 | this.oneOf=new ArrayList<>(oneOf.length); 40 | for(String s:oneOf){ 41 | this.oneOf.add(new PassportScopeElementOne(s)); 42 | } 43 | } 44 | 45 | public PassportScopeElementOneOfSeveral(){ 46 | 47 | } 48 | 49 | @Override 50 | Object toJSON(){ 51 | if(oneOf==null || oneOf.isEmpty()) 52 | return null; 53 | try{ 54 | JSONObject o=new JSONObject(); 55 | JSONArray oneOf=new JSONArray(); 56 | for(PassportScopeElementOne e:this.oneOf) 57 | oneOf.put(e.toJSON()); 58 | o.put("one_of", oneOf); 59 | if(selfie) 60 | o.put("selfie", true); 61 | if(translation) 62 | o.put("translation", true); 63 | return o; 64 | }catch(JSONException ignore){} 65 | return null; 66 | } 67 | 68 | @Override 69 | void validate() throws ScopeValidationException{ 70 | if(oneOf!=null){ 71 | int type=0; 72 | List idDocuments=Arrays.asList(PassportScope.PASSPORT, PassportScope.IDENTITY_CARD, PassportScope.INTERNAL_PASSPORT, PassportScope.DRIVER_LICENSE); 73 | List addressDocuments=Arrays.asList(PassportScope.UTILITY_BILL, PassportScope.BANK_STATEMENT, PassportScope.RENTAL_AGREEMENT, PassportScope.PASSPORT_REGISTRATION, PassportScope.TEMPORARY_REGISTRATION); 74 | for(PassportScopeElementOne el:oneOf){ 75 | el.validate(); 76 | if(Arrays.asList(PassportScope.PERSONAL_DETAILS, PassportScope.PHONE_NUMBER, PassportScope.EMAIL, PassportScope.ADDRESS).contains(el.type)) 77 | throw new ScopeValidationException("one_of can only be used with documents"); 78 | if(PassportScope.ID_DOCUMENT.equals(el.type) || PassportScope.ADDRESS_DOCUMENT.equals(el.type)) 79 | throw new ScopeValidationException("one_of can only be used when exact document types are specified"); 80 | int docType=0; 81 | if(idDocuments.contains(el.type)) 82 | docType=1; 83 | else if(addressDocuments.contains(el.type)) 84 | docType=2; 85 | if(type==0) 86 | type=docType; 87 | if(docType!=0 && type!=docType) 88 | throw new ScopeValidationException("One PassportScopeElementOneOfSeveral object can only contain documents of one type"); 89 | } 90 | } 91 | } 92 | 93 | /** 94 | * Request selfie 95 | * @see PassportScopeElementOneOfSeveral#selfie 96 | * @return this object for chaining 97 | */ 98 | public PassportScopeElementOneOfSeveral withSelfie(){ 99 | selfie=true; 100 | return this; 101 | } 102 | 103 | /** 104 | * Request translation 105 | * @see PassportScopeElementOneOfSeveral#translation 106 | * @return this object for chaining 107 | */ 108 | public PassportScopeElementOneOfSeveral withTranslation(){ 109 | translation=true; 110 | return this; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /telegrampassport/src/main/java/org/telegram/passport/ScopeValidationException.java: -------------------------------------------------------------------------------- 1 | package org.telegram.passport; 2 | 3 | /** 4 | * An exception thrown when {@link org.telegram.passport.TelegramPassport.AuthRequest#scope} contains an invalid combination of parameters. 5 | */ 6 | public class ScopeValidationException extends Exception{ 7 | public ScopeValidationException(String message){ 8 | super(message); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /telegrampassport/src/main/java/org/telegram/passport/TelegramLoginButton.java: -------------------------------------------------------------------------------- 1 | package org.telegram.passport; 2 | 3 | import android.annotation.TargetApi; 4 | import android.content.Context; 5 | import android.content.res.ColorStateList; 6 | import android.content.res.TypedArray; 7 | import android.graphics.Canvas; 8 | import android.graphics.ColorFilter; 9 | import android.graphics.Outline; 10 | import android.graphics.Paint; 11 | import android.graphics.RectF; 12 | import android.graphics.Typeface; 13 | import android.graphics.drawable.ColorDrawable; 14 | import android.graphics.drawable.Drawable; 15 | import android.graphics.drawable.LayerDrawable; 16 | import android.graphics.drawable.RippleDrawable; 17 | import android.graphics.drawable.StateListDrawable; 18 | import android.os.Build; 19 | import android.util.AttributeSet; 20 | import android.util.TypedValue; 21 | import android.view.Gravity; 22 | import android.widget.Button; 23 | 24 | /** 25 | * A {@link android.widget.Button} for use with Telegram login. 26 | *
27 | * Please note that this button doesn't perform any actions on its own. You're supposed to set an {@link android.view.View.OnClickListener} on it to perform actual login. 28 | */ 29 | public class TelegramLoginButton extends Button{ 30 | 31 | private float dp=getResources().getDisplayMetrics().density; 32 | private DynamicRoundRectDrawable background; 33 | private DynamicRoundRectDrawable overlay; 34 | 35 | public TelegramLoginButton(Context context){ 36 | super(context); 37 | init(null); 38 | } 39 | 40 | public TelegramLoginButton(Context context, AttributeSet attrs){ 41 | super(context, attrs); 42 | init(attrs); 43 | } 44 | 45 | public TelegramLoginButton(Context context, AttributeSet attrs, int defStyleAttr){ 46 | super(context, attrs, defStyleAttr); 47 | init(attrs); 48 | } 49 | 50 | private void init(AttributeSet attrs){ 51 | background=new DynamicRoundRectDrawable(); 52 | setTextColor(0xFFFFFFFF); 53 | setText(R.string.PassportSDK_LogInWithTelegram); 54 | setAllCaps(false); 55 | setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); 56 | setGravity(Gravity.CENTER); 57 | if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP){ 58 | setElevation(0); 59 | setStateListAnimator(null); 60 | setTypeface(Typeface.create("sans-serif-medium", Typeface.NORMAL)); 61 | 62 | ColorStateList stateList=new ColorStateList(new int[][]{{android.R.attr.state_pressed},{}}, new int[]{0x20000000, 0x20000000}); 63 | RippleDrawable ripple=new RippleDrawable(stateList, background, background); 64 | setBackgroundDrawable(ripple); 65 | }else{ 66 | setTypeface(Typeface.DEFAULT_BOLD); 67 | 68 | overlay=new DynamicRoundRectDrawable(); 69 | overlay.setColor(0x18000000); 70 | StateListDrawable stateList=new StateListDrawable(); 71 | stateList.addState(new int[]{android.R.attr.state_pressed}, overlay); 72 | stateList.addState(new int[]{}, new ColorDrawable(0)); 73 | stateList.setExitFadeDuration(250); 74 | stateList.setEnterFadeDuration(100); 75 | LayerDrawable layerList=new LayerDrawable(new Drawable[]{background, stateList}); 76 | setBackgroundDrawable(layerList); 77 | } 78 | setPadding(Math.round(16*dp), 0, Math.round(21*dp), 0); 79 | if(attrs!=null){ 80 | TypedArray a=getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.TelegramLoginButton, 0, 0); 81 | try{ 82 | float roundness=a.getFloat(R.styleable.TelegramLoginButton_cornerRoundness, .3f); 83 | setCornerRoundness(roundness); 84 | }finally{ 85 | a.recycle(); 86 | } 87 | } 88 | if(Build.VERSION.SDK_INT>=17) 89 | setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.telegram_logo, 0, 0, 0); 90 | else 91 | setCompoundDrawablesWithIntrinsicBounds(R.drawable.telegram_logo, 0, 0, 0); 92 | setCompoundDrawablePadding(Math.round(16*dp)); 93 | } 94 | 95 | @Override 96 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ 97 | super.onMeasure(widthMeasureSpec, Math.round(47*dp) | MeasureSpec.EXACTLY); 98 | } 99 | 100 | /** 101 | * Set the roundness of the button corners. Default value is 0.3. 102 | * @param roundness the amount of corner roundness, where 0 is a completely straight corner and 1 is completely round. 103 | */ 104 | public void setCornerRoundness(float roundness){ 105 | background.setRadiusPercent(roundness); 106 | if(overlay!=null) 107 | overlay.setRadiusPercent(roundness); 108 | } 109 | 110 | private class DynamicRoundRectDrawable extends Drawable{ 111 | 112 | private RectF rect=new RectF(); 113 | private Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG); 114 | private float radiusPercent=0f; 115 | private int initialAlpha=255; 116 | 117 | public DynamicRoundRectDrawable(){ 118 | paint.setColor(0xFF349ff3); 119 | } 120 | 121 | @Override 122 | public void draw(Canvas canvas){ 123 | rect.set(getBounds()); 124 | float radius=rect.height()/2f*radiusPercent; 125 | canvas.drawRoundRect(rect, radius, radius, paint); 126 | } 127 | 128 | @Override 129 | public void setAlpha(int alpha){ 130 | paint.setAlpha(Math.round(initialAlpha*alpha/255f)); 131 | invalidateSelf(); 132 | } 133 | 134 | @Override 135 | public void setColorFilter(ColorFilter colorFilter){ 136 | 137 | } 138 | 139 | @Override 140 | public int getOpacity(){ 141 | return 0; 142 | } 143 | 144 | public void setColor(int color){ 145 | paint.setColor(color); 146 | initialAlpha=paint.getAlpha(); 147 | } 148 | 149 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 150 | @Override 151 | public void getOutline(Outline outline){ 152 | outline.setRoundRect(getBounds(), getBounds().height()/2f*radiusPercent); 153 | } 154 | 155 | public void setRadiusPercent(float radiusPercent){ 156 | this.radiusPercent=radiusPercent; 157 | invalidateSelf(); 158 | } 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /telegrampassport/src/main/java/org/telegram/passport/TelegramPassport.java: -------------------------------------------------------------------------------- 1 | package org.telegram.passport; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.content.DialogInterface; 6 | import android.content.Intent; 7 | import android.content.pm.PackageManager; 8 | import android.net.Uri; 9 | import android.os.Build; 10 | import android.text.Html; 11 | import android.text.TextUtils; 12 | import android.util.Base64; 13 | import android.util.TypedValue; 14 | import android.view.View; 15 | import android.widget.ImageView; 16 | import android.widget.LinearLayout; 17 | import android.widget.TextView; 18 | 19 | import org.json.JSONArray; 20 | 21 | import java.security.KeyFactory; 22 | import java.security.spec.X509EncodedKeySpec; 23 | 24 | /** 25 | * A collection of utility methods and constants to use with Telegram Passport. 26 | */ 27 | public class TelegramPassport{ 28 | 29 | /** 30 | * Intent action to open a Telegram Passport authorization activity in a client app 31 | */ 32 | public static final String ACTION_AUTHORIZE="org.telegram.passport.AUTHORIZE"; 33 | 34 | /** 35 | * Activity result code: unrecoverable error 36 | */ 37 | public static final int RESULT_ERROR=Activity.RESULT_FIRST_USER; 38 | 39 | 40 | /** 41 | * Start the authorization flow for Telegram Passport. If Telegram app is installed, this opens it. 42 | * If it isn't, an alert is shown suggesting to install it. 43 | * @param activity calling activity 44 | * @param params AuthRequest to pass to the Telegram app 45 | * @param customRequestCode request code to be used in {@link android.app.Activity#startActivityForResult} 46 | */ 47 | public static void request(final Activity activity, AuthRequest params, int customRequestCode){ 48 | Intent intent=getAuthIntent(params); 49 | if(intent.resolveActivity(activity.getPackageManager())==null){ 50 | showAppInstallAlert(activity); 51 | return; 52 | } 53 | activity.startActivityForResult(intent, customRequestCode); 54 | } 55 | 56 | /** 57 | * Serialize authorization parameters into an Intent for later use in {@link android.app.Activity#startActivityForResult}. 58 | * Before launching this intent, make sure to check that there's Telegram app installed to handle it. 59 | * @param params AuthRequest to pass to the Telegram app 60 | * @return An intent 61 | * @throws IllegalArgumentException if the AuthRequest object isn't filled in correctly 62 | */ 63 | public static Intent getAuthIntent(AuthRequest params){ 64 | performSanityCheck(params); 65 | Intent intent=new Intent(ACTION_AUTHORIZE); 66 | intent.putExtra("bot_id", params.botID); 67 | intent.putExtra("scope", params.scope.toJSON().toString()); 68 | intent.putExtra("public_key", params.publicKey); 69 | intent.putExtra("payload", "nonce"); // this is needed for the older versions so it passes all the checks to get the "app outdated" error from the server 70 | intent.putExtra("nonce", params.nonce); 71 | return intent; 72 | } 73 | 74 | /** 75 | * Show an app installation alert, in case you need to do that yourself. 76 | * @param activity calling Activity 77 | */ 78 | public static void showAppInstallAlert(final Activity activity){ 79 | String appName=null; 80 | try{ 81 | PackageManager pm=activity.getPackageManager(); 82 | appName=pm.getApplicationLabel(pm.getApplicationInfo(activity.getPackageName(), 0)).toString().replace("<", "<"); 83 | }catch(PackageManager.NameNotFoundException ignore){} 84 | ImageView banner=new ImageView(activity); 85 | banner.setImageResource(R.drawable.telegram_logo_large); 86 | banner.setBackgroundColor(0xFF4fa9e6); 87 | float dp=activity.getResources().getDisplayMetrics().density; 88 | int pad=Math.round(34*dp); 89 | banner.setPadding(0, pad, 0, pad); 90 | LinearLayout content=new LinearLayout(activity); 91 | content.setOrientation(LinearLayout.VERTICAL); 92 | content.addView(banner); 93 | TextView alertText=new TextView(activity); 94 | alertText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); 95 | alertText.setTextColor(0xFF000000); 96 | alertText.setText(Html.fromHtml(activity.getString(R.string.PassportSDK_DownloadTelegram, appName).replaceAll("\\*\\*([^*]+)\\*\\*", "$1"))); 97 | alertText.setPadding(Math.round(24*dp), Math.round(24*dp), Math.round(24*dp), Build.VERSION.SDK_INT= 0"); 121 | if(params.scope==null) 122 | throw new IllegalArgumentException("scope must not be null"); 123 | if(params.scope.data==null || params.scope.data.isEmpty()) 124 | throw new IllegalArgumentException("scope must not be empty"); 125 | try{ 126 | params.scope.validate(); 127 | }catch(ScopeValidationException x){ 128 | throw new IllegalArgumentException("scope is invalid", x); 129 | } 130 | if(params.publicKey==null) 131 | throw new IllegalArgumentException("publicKey must not be null"); 132 | try{ 133 | X509EncodedKeySpec spec=new X509EncodedKeySpec(Base64.decode(params.publicKey.replaceAll("\\n", "").replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", ""), 0)); 134 | KeyFactory.getInstance("RSA").generatePublic(spec); 135 | }catch(Exception x){ 136 | throw new IllegalArgumentException("publicKey has invalid format", x); 137 | } 138 | if(TextUtils.isEmpty(params.nonce)) 139 | throw new IllegalArgumentException("nonce must not be empty"); 140 | } 141 | 142 | /** 143 | * This object represents a Telegram Passport authorization request. 144 | */ 145 | public static class AuthRequest{ 146 | /** 147 | * Bot ID. This is the number at the beginning of the bot token. 148 | * Required. 149 | */ 150 | public int botID; 151 | 152 | /** 153 | * List of the names of fields you want to request. 154 | * Required. 155 | */ 156 | public PassportScope scope; 157 | 158 | /** 159 | * The public key of the bot. 160 | * Required. 161 | */ 162 | public String publicKey; 163 | 164 | /** 165 | * An arbitrary string that is passed to the bot server. 166 | * Required. 167 | */ 168 | public String nonce; 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/drawable/telegram_logo.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 14 | 17 | 21 | 25 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/drawable/telegram_logo_large.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 14 | 17 | 21 | 25 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/values-ar/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | إلغاء 4 | فتح جوجل بلاي 5 | تحتاج تيليجرام لتسجيل الدخول إلى **%s**. هل تريد تنزيله الآن؟ 6 | تسجيل الدخول عبر تيليجرام 7 | جواز تيليجرام 8 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/values-de/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Abbrechen 4 | Google Play öffnen 5 | Du brauchst Telegram, um dich bei **%s** anmelden zu können. Möchtest du es jetzt installieren? 6 | Mit Telegram anmelden 7 | Telegram Passport 8 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/values-es/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Cancelar 4 | Abrir Google Play 5 | Necesitas Telegram para registrarte en **%s**. ¿Quieres instalarla ahora? 6 | Iniciar sesión con Telegram 7 | Telegram Passport 8 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/values-fa/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | لغو 4 | باز کردن Google Play 5 | شما جهت ورود به حساب کاربری خود در **%s** به تلگرام احتیاج دارید. آیا تمایل دارید آن را الان نصب کنید؟ 6 | ورود با حساب کاربری تلگرام 7 | گذرنامه تلگرامی 8 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/values-fr/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Annuler 4 | Ouvrir Google Play 5 | Vous avez besoin de Telegram pour vous connecter à **%s**. Voulez-vous l\'installer maintenant ? 6 | Connexion avec Telegram 7 | Telegram Passport 8 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/values-id/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Batal 4 | Buka Google Play 5 | Anda membutuhkan Telegram untuk masuk ke %s. Apakah Anda ingin memasangnya sekarang? 6 | Masuk dengan Telegram 7 | Paspor Telegram 8 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/values-it/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Annulla 4 | Apri Google Play 5 | Hai bisogno di Telegram per accedere a **%s**. Vuoi installarlo ora? 6 | Accedi con Telegram 7 | Telegram Passport 8 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/values-ko/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 취소 4 | 구글 플레이 열기 5 | %s에 로그인하려면 텔레그램이 필요합니다. 지금 설치하시겠습니까? 6 | 텔레그램으로 로그인 7 | 텔레그램 여권 8 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/values-ms/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Batal 4 | Buka Google Play 5 | Anda perlu Telegram untuk log masuk ke **%s**. Adakah anda ingin pasangnya sekarang? 6 | Log masuk dengan Telegram 7 | Paspot Telegram 8 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/values-nl/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Annuleren 4 | Google Play openen 5 | Je hebt Telegram nodig om in te loggen op **%s**, nu installeren? 6 | Inloggen met Telegram 7 | Telegram Passport 8 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/values-pt-rBR/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Entrar com Telegram 4 | Telegram Passport 5 | Você precisa do Telegram para entrar em **%s**. Gostaria de instalar agora? 6 | Abrir Google Play 7 | Cancelar 8 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/values-ru/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Отмена 4 | Открыть Google Play 5 | Чтобы авторизоваться в **%s**, требуется Telegram. Хотите установить его сейчас? 6 | Войти через Telegram 7 | Telegram Passport 8 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/values-uk/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Скасувати 4 | Відкрити Google Play 5 | Вам потрібен Telegram щоб увійти до **%s**. Бажаєте встановити його зараз? 6 | Увійти через Telegram 7 | Telegram Passport 8 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Log in with Telegram 4 | Telegram Passport 5 | You need Telegram to log in to **%s**. Would you like to install it now? 6 | Open Google Play 7 | Cancel 8 | 9 | -------------------------------------------------------------------------------- /telegrampassport/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 13 | 14 | 19 | 20 | 22 | 23 | --------------------------------------------------------------------------------