├── .gitattributes
├── .github
└── workflows
│ ├── merge_request.yml
│ └── publish.yml
├── .gitignore
├── .idea
└── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── CHANGELOG.md
├── LICENSE
├── MIGRATION.md
├── README.md
├── app-demo
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── ru
│ │ └── tinkoff
│ │ └── core
│ │ └── app_demo_partner
│ │ └── TinkoffIdSignInButtonTest.kt
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── ru
│ │ └── tinkoff
│ │ └── core
│ │ └── app_demo_partner
│ │ ├── PartnerActivity.kt
│ │ └── PartnerPresenter.kt
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable
│ └── ic_launcher_background.xml
│ ├── layout
│ └── activity_partner.xml
│ ├── mipmap-anydpi-v26
│ └── ic_launcher.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ └── ic_launcher_foreground.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ └── ic_launcher_foreground.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_foreground.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_foreground.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_foreground.png
│ ├── values-ru
│ └── strings.xml
│ ├── values
│ ├── ic_launcher_background.xml
│ └── strings.xml
│ └── xml
│ ├── data_extraction_rules.xml
│ └── network_security_config.xml
├── build.gradle
├── gradle.properties
├── gradle
├── plugin
│ ├── android.gradle
│ ├── config
│ │ └── detekt.yml
│ ├── detekt.gradle
│ ├── kotlin-library.gradle
│ └── publish-lib.gradle
├── versions.gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── imgs
└── tinkoff_id_sign_in_button
│ ├── compact.png
│ └── standard.png
├── settings.gradle
└── tinkoff-id
├── .gitignore
├── build.gradle
├── gradle.properties
└── src
├── main
├── AndroidManifest.xml
├── java
│ └── ru
│ │ └── tinkoff
│ │ └── core
│ │ └── tinkoffId
│ │ ├── AppLinkUtil.kt
│ │ ├── TinkoffCall.kt
│ │ ├── TinkoffIdAuth.kt
│ │ ├── TinkoffIdStatusCode.kt
│ │ ├── TinkoffPartnerApiService.kt
│ │ ├── TinkoffTokenPayload.kt
│ │ ├── api
│ │ └── TinkoffIdApi.kt
│ │ ├── codeVerifier
│ │ ├── CodeVerifierStore.kt
│ │ └── CodeVerifierUtil.kt
│ │ ├── error
│ │ ├── TinkoffErrorMessage.kt
│ │ ├── TinkoffRequestException.kt
│ │ ├── TinkoffTokenErrorConstants.kt
│ │ └── TokenSignOutErrorConstants.kt
│ │ └── ui
│ │ ├── TinkoffIdSignInButton.kt
│ │ └── webView
│ │ ├── TinkoffWebViewAuthActivity.kt
│ │ ├── TinkoffWebViewAuthPresenter.kt
│ │ ├── TinkoffWebViewClient.kt
│ │ ├── TinkoffWebViewListener.kt
│ │ └── TinkoffWebViewUiData.kt
└── res
│ ├── drawable-hdpi
│ ├── tinkoff_id_tinkoff_logo.png
│ ├── tinkoff_id_tinkoff_small_logo.png
│ └── tinkoff_id_tinkoff_small_logo_border.png
│ ├── drawable-mdpi
│ ├── tinkoff_id_tinkoff_logo.png
│ ├── tinkoff_id_tinkoff_small_logo.png
│ └── tinkoff_id_tinkoff_small_logo_border.png
│ ├── drawable-xhdpi
│ ├── tinkoff_id_tinkoff_logo.png
│ ├── tinkoff_id_tinkoff_small_logo.png
│ └── tinkoff_id_tinkoff_small_logo_border.png
│ ├── drawable-xxhdpi
│ ├── tinkoff_id_tinkoff_logo.png
│ ├── tinkoff_id_tinkoff_small_logo.png
│ └── tinkoff_id_tinkoff_small_logo_border.png
│ ├── drawable-xxxhdpi
│ ├── tinkoff_id_tinkoff_logo.png
│ ├── tinkoff_id_tinkoff_small_logo.png
│ └── tinkoff_id_tinkoff_small_logo_border.png
│ ├── drawable
│ ├── tinkoff_id_badge_background_black_style.xml
│ ├── tinkoff_id_badge_background_gray_style.xml
│ ├── tinkoff_id_badge_background_yellow_style.xml
│ ├── tinkoff_id_close.xml
│ ├── tinkoff_id_compact_background_black_style.xml
│ ├── tinkoff_id_compact_background_gray_style.xml
│ ├── tinkoff_id_compact_background_yellow_style.xml
│ └── tinkoff_id_reload_icon.xml
│ ├── font
│ └── neue_haas_unica_w1g.ttf
│ ├── layout
│ └── tinkoff_id_web_view_activity.xml
│ ├── menu
│ └── tinkoff_id_web_view_auth_menu.xml
│ ├── values-en
│ └── strings.xml
│ ├── values-night
│ └── colors.xml
│ └── values
│ ├── attr.xml
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
└── test
└── java
└── ru
└── tinkoff
└── core
└── tinkoffId
├── AppLinkUtilTest.kt
├── TinkoffIdApiTest.kt
├── TinkoffIdAuthTest.kt
├── TinkoffIdSignInButtonTest.kt
└── TinkoffPartnerApiServiceTest.kt
/.gitattributes:
--------------------------------------------------------------------------------
1 | changelog.md merge=union
--------------------------------------------------------------------------------
/.github/workflows/merge_request.yml:
--------------------------------------------------------------------------------
1 | name: merge request
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - 'main'
7 |
8 | jobs:
9 | check:
10 | uses: tinkoff-mobile-tech/workflows/.github/workflows/android_lib.merge_request.yml@v1
11 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: publish
2 |
3 | on:
4 | workflow_dispatch:
5 |
6 |
7 | jobs:
8 | publish:
9 | uses: tinkoff-mobile-tech/workflows/.github/workflows/android_lib.publish.yml@v1
10 | secrets:
11 | gpg_key: ${{ secrets.GPG_KEY }}
12 | sign_ossrh_gradle_properties: ${{ secrets.SIGN_OSSRH_GRADLE_PROPERTIES }}
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle/
2 | .idea
3 | !.idea/codeStyles
4 | build/
5 | .DS_Store
6 |
7 | /local.properties
8 | /gradle.properties
9 | installlocal.bat
10 |
11 | *.iml
12 | *.eml
13 | *.iws
14 |
15 | gradle/plugin/custom.gradle
16 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | xmlns:android
37 |
38 | ^$
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | xmlns:.*
48 |
49 | ^$
50 |
51 |
52 | BY_NAME
53 |
54 |
55 |
56 |
57 |
58 |
59 | .*:id
60 |
61 | http://schemas.android.com/apk/res/android
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | .*:name
71 |
72 | http://schemas.android.com/apk/res/android
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | name
82 |
83 | ^$
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 | style
93 |
94 | ^$
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 | .*
104 |
105 | ^$
106 |
107 |
108 | BY_NAME
109 |
110 |
111 |
112 |
113 |
114 |
115 | .*
116 |
117 | http://schemas.android.com/apk/res/android
118 |
119 |
120 | ANDROID_ATTRIBUTE_ORDER
121 |
122 |
123 |
124 |
125 |
126 |
127 | .*
128 |
129 | .*
130 |
131 |
132 | BY_NAME
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 1.1.1
2 |
3 | #### Fixed
4 | #### Changes
5 | #### Additions
6 |
7 | ## 1.1.0
8 |
9 | #### Fixed
10 | #### Changes
11 | #### Additions
12 |
13 | - [app-demo], [tinkoff-id] Добавлен флоу авторизации через WebView MC-7723
14 |
15 | ## 1.0.5
16 |
17 | #### Fixed
18 |
19 | - [tinkoff-id] Внесены правки в документацию MC-6740
20 |
21 | #### Changes
22 |
23 | - [tinkoff-id] update versions of target and compile sdk, AGP and Gradle, dependencies MC-9132
24 |
25 | #### Additions
26 |
27 | - [tinkoff-id] В Intent для запуска авторизации добавлен параметр версии SDK MC-6740
28 |
29 | ## 1.0.4
30 |
31 | #### Fixed
32 | #### Changes
33 | #### Additions
34 | - [tinkoff-id] add self-signed SSL certificates MC-7689
35 |
36 | ## 1.0.3
37 |
38 | #### Fixed
39 | #### Changes
40 | - [app-demo], [tinkoff-id] redesign TinkoffIdSignInButton MC-6146
41 | #### Additions
42 |
43 | ## 1.0.2
44 |
45 | #### Fixed
46 | #### Changes
47 | - [app-demo], [tinkoff-id] bump up API versions (targetSdk and compileSdk to 31) and dependencies versions MC-5659
48 | #### Additions
49 |
50 | ## 1.0.1
51 |
52 | #### Fixed
53 | #### Changes
54 | #### Additions
55 | - Added redirect_uri configuration logic
56 |
57 | ## 1.0.0
58 |
59 | #### Fixed
60 | #### Changes
61 | #### Additions
62 |
63 | [app-demo]: app-demo
64 | [tinkoff-id]: tinkoff-id
65 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
2 | 1. Definitions.
3 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
4 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
5 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
6 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
7 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
8 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
9 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
10 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
11 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
12 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
13 | 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
14 | 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
15 | 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: You must give any other recipients of the Work or Derivative Works a copy of this License; and
16 | You must cause any modified files to carry prominent notices stating that You changed the files; and
17 | You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
18 | If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
19 | 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
20 | 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
21 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
22 | 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
23 | 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
24 |
25 | УСЛОВИЯ ИСПОЛЬЗОВАНИЯ, ВОСПРОИЗВЕДЕНИЯ И РАСПРОСТРАНЕНИЯ
26 | 1. Термины и определения.
27 | Термин «Лицензия» означает условия использования, копирования и распространения, изложенные в Разделах 1-9 настоящего документа.
28 | Термин «Лицензиар» относится к владельцу авторских прав или юридическому лицу, которое уполномочено владельцем авторских прав для предоставления Лицензии.
29 | Термин «Юридическое лицо» означает объединение действующей организации и всех прочих организаций, которые управляют, управляются, или находятся под общим управлением данного лица. В применении к данному термину, «управление» означает (i) право напрямую или косвенно осуществлять управление такой организацией на основании контракта или иным образом, либо (ii) право собственности на пятьдесят процентов (50%) или более акций, выпущенных в обращение, либо (iii) бенефициарное владение такой организацией.
30 | Термин «Вы» или «Ваш» означает частное или юридическое лицо, которое пользуется правами в соответствии с данной Лицензией.
31 | Форма «Источник» означает предпочтительную форму внесения изменений, включая, но не ограничиваясь исходным программным кодом, источником документации и конфигурационными файлами.
32 | Форма «Объект» означает всякую форму, являющуюся результатом автоматического преобразования или трансляции формы источника, включая, но не ограничиваясь объектным кодом, сгенерированной документацией или конвертацией в прочие виды носителей информации.
33 | «Произведение» означает авторское произведение, в форме источника или объекта, предоставленное согласно Лицензии, как обозначено в уведомлении об авторских правах, которое включено или прикреплено к произведению (пример приводится ниже в Приложении).
34 | Термин «Производные произведения» означает произведение, в форме источника или объекта, которое основано на (или получено из) произведении и по отношению к которому все редакторские правки, примечания, уточнения, или другие изменения, представляют в целом авторское произведение. Понятие Производные произведения не включает в себя произведения, которые обособлены от, или только связаны (или связаны по наименованию) с интерфейсами Произведения или его Производных произведений.
35 | «Последующая разработка» означает любое авторское произведение, включая исходную версию Произведения и любые изменения или дополнения к данному Произведению или его Производным произведениям, которые были намерено представлены Лицензиару для включения в Произведение владельцем авторского права или физическим или юридическим лицом, уполномоченным представлять изменения на правах владельца авторских прав. В рамках данного определения «представление» означает информацию в электронном, устном или письменном виде, отправленную Лицензиару или его представителям, включая, но не ограничиваясь передачей информации по электронной почте, через систему контроля исходного кода и систему контроля версий, под управлением или на правах Лицензиара с целью обсуждения и улучшения Произведения, но исключая информацию, которая выделена или письменно обозначена владельцем авторского права как «Не являющаяся Последующей разработкой».
36 | Под Последующим разработчиком подразумевается Лицензиар или физическое или юридическое лицо от имени которого Лицензиаром была получена Последующая разработка и впоследствии включена в Произведение.
37 | 2. Предоставление лицензии на авторское право. В рамках данной Лицензии, каждый Последующий разработчик предоставляет Вам бессрочную, универсальную, неисключительную, свободную, неотзываемую лицензию на воспроизведение, открытую демонстрацию, открытое использование, сублицензирование и распространение Произведения и Производных произведений в форме источника или объекта.
38 | 3. Предоставление патентной лицензии. В рамках данной Лицензии, каждый Последующий разработчик предоставляет Вам бессрочную, универсальную, неисключительную, свободную, неотзываемую (за исключением положений, приведенных в данном отделе) патентную лицензию на изготовление, заказ на изготовление, использование, предложение о продаже, продажу, импорт или передачу Произведения, в тех случаях, когда лицензия относится только к патентным притязаниям, лицензируемыми Последующим разработчиком, и которые нарушают права своими Последующими разработками или сочетанием из Последующих разработок и Произведения к которому эти Последующие разработки были представлены. Если вы начинаете патентный спор против любой организации (включая встречный или перекрестный иск в судебном процессе) утверждая, что Произведение или Последующая разработка содержит прямое или косвенное нарушение патентного права, то любая патентная лицензия переданная Вам согласно данной Лицензии на это Произведение прекращает действовать с момента подачи документов о патентном споре.
39 | 4. Распространение. Вы можете воспроизводить и распространять копии Произведения и его Производных произведений с изменениями или без, в форме источника или объекта, принимая во внимание то, что Вы действуете согласно следующим условиям:
40 | Вы должны предоставить копию данной Лицензии любому получившему Произведение или Производные произведения, и
41 | Любые измененные Вами файлы должны содержать хорошо заметную пометку, что они были изменены, а также
42 | При дальнейшем распространении формы источника любых Производных произведений должны сохраняться все заявления об авторских правах, патентах, товарных знаках и упоминаниях, присутствующие в форме источника Произведения, за исключением тех заявлений, которые не касаются любой части Производных произведений, и
43 | Если Произведение содержит текстовый файл «Уведомление», то любые Производные произведения, которые Вы распространяете, должны включать его удобочитаемую копию, за исключением тех заявлений, которые не касаются любой части Производных произведений, по крайней мере, копия должна находиться в одном из следующих мест: в текстовом файле «Notice», распространяемом как часть Производных произведений; в форме источника или документации, если таковая предоставляется наряду с Производными произведениями; или в процессе отображения, создаваемого, в случае если и где бы эти сторонние заявления не появились. Содержимое файла «Notice» предоставляется только для информационных целей и не изменяет Лицензию. Вы можете добавить Ваши собственные уведомления об использовании торгового знака в Производные произведения, которые Вы распространяете, наряду с или как приложение к тексту Notice, принимая во внимание, что подобные дополнительные уведомления не могут быть истолкованы как изменение Лицензии.
44 | Вы можете добавить к изменениям Ваше собственное заявление об авторских правах и можете предоставить дополнительные или другие лицензионные условия для использования, копирования или распространения Ваших модификаций, или для использования Производных произведений в целом, при условии, что Вы используете, копируете и распространяете Произведение в соответствии с условиями, изложенными в данной Лицензии.
45 | 5. Представление Последующих разработок. Если Вы явно не утверждаете другого, любая Последующая разработка, намеренно представленная Вами Лицензиару для включения в Произведение, должна соответствовать условиям данной Лицензии, исключая любые дополнительные условия. Несмотря на вышеизложенное, ничто в данном документе не может заместить или изменить условия отдельного лицензионного соглашения, которое вы могли заключить с Лицензиаром относительно Последующих разработок.
46 | 6. Товарные знаки. Данная Лицензия не дает разрешения на использование торговых наименований, товарных знаков, знаков услуг или названий продуктов, принадлежащих Лицензиару, исключая ситуацию, когда они могут потребоваться для обоснованного и обычного использования при описании источника Произведения и воспроизведении содержимого файла Notice.
47 | 7. Отказ от гарантийных обязательств. Лицензиар предоставляет Произведение (и каждый Последующий разработчик предоставляет Последующие разработки) "КАК ЕСТЬ" и любые явные или неявные гарантии, включая, без ограничений, гарантии ПРАВ СОБСТВЕННОСТИ, НЕНАРУШЕНИЕ ПРАВ, КОММЕРЧЕСКОЙ ПРИГОДНОСТИ И ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ, ОТВЕРГАЮТСЯ. Вы несете ответственность исключительно за определение пригодности использования или распределения Произведения и принимаете любые риски связанные с осуществлением полномочий по данному Лицензионному соглашению.
48 | 8. Ограничение ответственности. Ни при каких условиях Последующий разработчик не несет ответственности перед Вами за убытки, включая любые прямые, косвенные, умышленные, случайные или последующие убытки любого характера проистекающие из данного Лицензионного соглашения или из использования или невозможности использования Произведения (включая, но не ограничиваясь, убытками, возникшими в результате потери деловой репутации, прекращении работы, аварии или неисправности или любых коммерческих убытков или потерь) даже если Последующий разработчик был предупрежден о возможности такого ущерба.
49 | 9. Принятие гарантийных обязательств или Дополнительные обязательства. В процессе распространения копий Произведения и его Производных произведений, Вы можете предложить и взимать плату за принятие обязательств по предоставлению поддержки, гарантийных обязательств, гарантии от убытков и других обязательств по ответственности и/или прав в соответствии с данной Лицензией. Тем не менее, принимая на себя подобные обязательства, Вы можете действовать только от своего собственного имени и на свою исключительную ответственность, не от имени любого другого Последующего разработчика, и только в случае, если вы согласны урегулировать, возместить убытки и защитить каждого Последующего разработчика от навлеченной ответственности и претензий, предъявленных Последующему разработчику, на основании принятия вами гарантийных обязательств или дополнительной ответственности.
--------------------------------------------------------------------------------
/MIGRATION.md:
--------------------------------------------------------------------------------
1 | # Документ по миграции
2 |
3 | ## 1.0.6 -> 1.1.0
4 |
5 | В связи с добавлением альтернативного способа авторизации через веб Тинькофф с помощью WebView,
6 | переработана логика метода `createTinkoffAuthIntent(callbackUrl: Uri): Intent`. Теперь внутри него, на основе значения
7 | `isTinkoffAppAuthAvailable(): Boolean`, происходит создание Intent для открытия или приложения Тинькофф,
8 | или `TinkoffWebViewAuthActivity` (для прохождения авторизации в вебе).
9 |
10 | Рекомендуется использовать `createTinkoffAuthIntent(callbackUrl: Uri): Intent`, чтобы пользователю в любом случае была
11 | доступна авторизации через Тинькофф:
12 |
13 | **Before**:
14 |
15 | ```kotlin
16 | if (tinkoffPartnerAuth.isTinkoffAuthAvailable()) {
17 | val intent = tinkoffPartnerAuth.createTinkoffAuthIntent(callbackUrl)
18 | startActivity(intent)
19 | } else {
20 | // The logic of disabling authorization via Tinkoff
21 | }
22 | ```
23 |
24 | **After**:
25 |
26 | ```kotlin
27 | val intent = tinkoffPartnerAuth.createTinkoffAuthIntent(callbackUrl)
28 | startActivity(intent)
29 | ```
30 |
31 | Изменения в методах класса `TinkoffIdAuth`:
32 | - `createTinkoffAuthIntent(callbackUrl: Uri): Intent` -> `createTinkoffAppAuthIntent(callbackUrl: Uri): Intent`
33 | - `isTinkoffAuthAvailable(): Boolean` -> `isTinkoffAppAuthAvailable(): Boolean`
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Tinkoff ID
2 |
3 | Tinkoff ID - SDK для авторизации пользователей Android приложений с помощью аккаунта Тинькофф.
4 |
5 | ## Предварительные этапы
6 |
7 | Для начала работы с Tinkoff ID в качестве партнера заполните заявку на
8 | подключение на [данной странице](https://www.tinkoff.ru/business/open-api/).
9 | После рассмотрения вашей заявки вы получите по электронной почте
10 | `Client ID` и пароль. Подробная инструкция доступна в [документации](https://business.tinkoff.ru/openapi/docs/#section/Partnerskij-scenarij)
11 |
12 | ## Установка
13 |
14 | Для начала работы добавьте следующую строчку в `build.gradle`:
15 |
16 | ```groovy
17 | implementation "ru.tinkoff.core.tinkoffauth:tinkoff-id:${version}"
18 | ```
19 |
20 | Так же необходимо добавить в [network-security-config](https://developer.android.com/training/articles/security-config) содержащий сертификаты от Минцифры и доп. сертификат от Тинькофф.
21 | Пример можно посмотреть в [app-demo](app-demo). Выглядит он так:
22 | ```xml
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | ```
34 |
35 | ## Требования к приложению
36 |
37 | Для работы SDK необходимо следующее:
38 |
39 | + Зарегистрированный идентификатор авторизуемого приложения (`client_id`)
40 | + Uri авторизуемого клиента, на который будет выполнен редирект по завершению авторизации (`redirectUri`)
41 | + Зарегистрированный авторизуемым приложением [AppLink](https://developer.android.com/training/app-links), который будет использоваться для возврата в приложение после авторизации. Использование DeepLink возможно, но не рекомендовано. (`callbackUrl`)
42 | + Авторизация через Тинькофф будет работать только начиная с версии Android 6.0, на более ранних версиях получить авторизационные данные не будет возможности.
43 |
44 | ## Интеграция
45 |
46 | ### Начало
47 |
48 | Все необходимое взаимодействие в библиотеке идет только через класс `TinkoffIdAuth`.
49 |
50 | Чтобы начать авторизациию через Тинькофф, создайте Intent с помощью `tinkoffIdAuth.createTinkoffAuthIntent(callbackUrl)` и запустите его.
51 | Внутри этого метода автоматически происходит создание Intent для открытия приложения Тинькофф, если оно доступно, иначе создается Intent
52 | для открытия `TinkoffWebViewAuthActivity`, в котором возможно прохождение авторизации через веб Тинькофф.
53 |
54 | Вы также сами можете выбирать, какой способ авторизации использовать.
55 | Сперва проверьте, есть ли возможность пройти авторизацию через приложение Тинькофф.
56 | Для этого используйте `tinkoffIdAuth.isTinkoffAppAuthAvailable()`.
57 | Если флаг `isTinkoffAppAuthAvailable == true`, значит у пользователя установлено приложение Тинькофф,
58 | через которое можно осуществить вход, используя `tinkoffIdAuth.createTinkoffAppAuthIntent(callbackUrl)`.
59 | Иначе можно запустить сценарий авторизации через WebView, используя `tinkoffIdAuth.createTinkoffWebViewAuthIntent(callbackUrl)`.
60 |
61 | ### Выполнение авторизации
62 |
63 | Для авторизации:
64 | 1. Необходимо создать объект `TinkoffIdAuth(applicationContext, clientId, redirectUri)` - это основной класс для работы с библиотекой.
65 | 2. Создать Intent для выбранного способа авторизации, передав в качестве аргумента `callbackUrl` - ваш AppLink/DeepLink (по данному uri приложение группы Тинькофф вернется обратно после процесса авторизации), запустить его
66 | ```kotlin
67 | val intent = tinkoffIdAuth.createTinkoffAuthIntent(callbackUrl)
68 | startActivity(intent)
69 | ```
70 | 3. После прохождения пользователем авторизации через Тинькофф, произойдет переход в ваше приложение на основе `callbackUrl`. В `intent.data` будет храниться информация по авторизации.
71 |
72 | ### Завершение авторизации
73 | Успешность авторизации можно проверить методом - `tinkoffIdAuth.getStatusCode(uriFromIntentData)`. Метод вернет статус `SUCCESS` или `CANCELLED_BY_USER`
74 |
75 | При успешной авторизации:
76 | 1. Нужно получить `TinkoffTokenPayload`, выполнив `getTinkoffTokenPayload(uri).getResponse()`. Данный метод необходимо выполнять в отличном от main потоке.
77 | 2. Полученный `TinkoffTokenPayload` будет содержать учетные данные пользователя
78 |
79 | При неуспешной авторизации придет статус в `intent.data` `CANCELLED_BY_USER` или приложение откроется без данных в `intent.data`.
80 |
81 | ### Перевыпуск авторизационных данных
82 |
83 | Для перевыпуска accessToken необходимо использовать метод
84 | ```kotlin
85 | fun obtainTokenPayload(refreshToken: String): TinkoffCall
86 | ```
87 |
88 | В него нужно передать refreshToken, полученный ранее. Выполнять вызов `getResponse()` необходимо не на main потоке
89 |
90 | ### Отзыв авторизационных данных
91 |
92 | Иногда может возникнуть ситуация, когда полученные авторизационные данные более не нужны.
93 | Например, при выходе, смене или отключении аккаунта пользователя в авторизованном приложении.
94 | В таком случае, приложению необходимо выполнить отзыв авторизационных данных с помощью методов:
95 |
96 | ```kotlin
97 | fun signOutByAccessToken(accessToken: String): TinkoffCall
98 | fun signOutByRefreshToken(refreshToken: String): TinkoffCall
99 | ```
100 |
101 | ### Хранение Refresh Token
102 |
103 | Желательно реализовать безопасное хранение `tinkoffTokenPayload.refreshToken` в приложении,
104 | так как он необходим для перевыпуска токенов.
105 |
106 | ### UI
107 |
108 | Чтобы подробнее ознакомиться со стайлгайдом по размещению кнопок перейдите по [ссылке](https://www.figma.com/file/Yj3o7yQotahvBxfIKhBmJc/Tinkoff-ID-guide)
109 |
110 | Библиотека предоставляет кнопку `TinkoffIdSignInButton.kt`.
111 | Пример по ее настройке доступен в `PartnerActivity.kt` и `activity_partner.xml`.
112 | Форма кнопки настраивается через атрибут `app:tinkoff_id_compact`, который может иметь значение `true` или `false` (по умолчанию).
113 | Стиль кнопки можно изменить с помощью атрибута `app:tinkoff_id_style`, который может иметь значение `black` / `gray` / `yellow` (по умолчанию).
114 | Если кнопка имеет стандартную форму, то можно дополнительно настроить основной текст (`app:tinkoff_id_title`), дополнительный текст на бейдже (`app:tinkoff_id_badge`), радиусы углов (`app:tinkoff_id_corner_radius`) и шрифт текста (`app:tinkoff_id_font`).
115 | Пример добавления кнопки:
116 |
117 | ```xml
118 |
128 | ```
129 |
130 | Виды кнопок:
131 |
132 | compact
133 | 
134 |
135 | standard
136 | 
137 |
138 | ## Структура публичной части SDK
139 |
140 | ### TinkoffIdAuth
141 |
142 | Базовый класс для работы c авторизацией
143 |
144 | | Функция | Описание |
145 | | ---------------------------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
146 | | `createTinkoffAuthIntent(callbackUrl: Uri): Intent` | Создает Intent для открытия приложения группы Тинькофф, если оно доступно, иначе для `TinkoffWebViewAuthActivity`, чтобы авторизоваться через веб Тинькофф. На вход принимает Uri для создания AppLink/DeepLink, по которому будет осуществлен переход после окончания процесса авторизации |
147 | | `isTinkoffAppAuthAvailable(): Boolean` | Выполняет проверку возможна ли авторизация через приложения группы Тинькофф на данном устройстве |
148 | | `createTinkoffAppAuthIntent(callbackUrl: Uri): Intent` | Создает Intent для открытия приложения группы Тинькофф для прохождения авторизации. На вход принимает Uri для создания AppLink/DeepLink, по которому будет осуществлен переход после окончания процесса авторизации |
149 | | `createTinkoffWebViewAuthIntent(callbackUrl: Uri): Intent` | Создает Intent для открытия `TinkoffWebViewAuthActivity` для прохождения авторизации в вебе. На вход принимает Uri для создания AppLink/DeepLink, по которому будет осуществлен переход после окончания процесса авторизации |
150 | | `getTinkoffTokenPayload(uri: Uri): TinkoffCall` | Возвращает объект, который позволяет получить синхронно информацию о токене, которая придет к вам в `intent.data` после авторизации в Тинькофф |
151 | | `getStatusCode(uri: Uri): TinkoffIdStatusCode?` | Позволяет получить статус выполнения авторизации из `intent.data` пришедшего к вам |
152 | | `obtainTokenPayload(refreshToken: String): TinkoffCall` | Возвращает объект, который позволяет синхронно обновить токен по рефреш токену полученному ранее |
153 | | `signOutByAccessToken(accessToken: String): TinkoffCall` | Возвращает объект, который позволяет синхронно разлогинить по accessToken |
154 | | `signOutByRefreshToken(refreshToken: String): TinkoffCall` | Возвращает объект, который позволяет синхронно разлогинить по refreshToken |
155 |
156 | ### TinkoffCall``
157 |
158 | Объект, который позволяет выполнить долгий запрос синхронно и получить `T` или отменить этот запрос.
159 |
160 | | Функция | Описание |
161 | | ---------------------------- |---------------------------------------------------------------|
162 | | `fun getResponse(): T` | Позволяет получить объект типа `T` |
163 | | `cancel()` | Отменяет запрос |
164 |
165 | ### TinkoffTokenPayload
166 |
167 | В результате успешной авторизации приложение получает объект `TinkoffTokenPayload`, содержащий следующие свойства:
168 |
169 | + `accessToken` - токен для обращения к API Тинькофф
170 | + `refreshToken` - токен, необходимый для получения нового `accessToken`
171 | + `idToken` - идентификатор пользователя в формате JWT
172 | + `expiresIn` - время, через которое `accessToken` станет неактуальным и нужно будет получить новый с помощью `obtainTokenPayload(refreshToken)`
173 |
174 | ### TinkoffIdStatusCode
175 |
176 | Enum со статусами пришедшими из приложения Тинькофф после попытки авторизации
177 |
178 | | Значение | Описание |
179 | | ---------------------------- |---------------------------------------------------------------|
180 | | `SUCCESS` | Авторизация в Тинькофф прошла успешно |
181 | | `CANCELLED_BY_USER` | Авторизация в Тинькофф была отменена пользователем |
182 |
183 | ### TinkoffRequestException
184 |
185 | Ошибка, происходящая во время выполнения запросов
186 |
187 | | Параметр | Описание |
188 | | ---------------------------- |---------------------------------------------------------------|
189 | | `reason: Throwable` | Причина ошибки |
190 | | `message: String?` | Сообщение к ошибке |
191 | | `errorMessage: TinkoffErrorMessage?` | Объект описывающий ошибку и причину происхождения с точки зрения апи |
192 |
193 | ### TinkoffErrorMessage
194 |
195 | Объект, описывающий ошибку и причину происхождения с точки зрения апи
196 |
197 | | Параметр | Описание |
198 | | ---------------------------- |---------------------------------------------------------------|
199 | | `message: String?` | Человекочитаемый тип ошибки от АПИ |
200 | | `public val errorType: Int` | Тип ошибки, принимающий значение из TinkoffTokenErrorConstants, TokenSignOutErrorConstants |
201 |
202 | ### TinkoffTokenErrorConstants
203 |
204 | Ошибки, возвращаемые во время получения и обновления токена
205 |
206 | | Значение | Описание |
207 | | ---------------------------- |---------------------------------------------------------------|
208 | | `INVALID_REQUEST` | Не хватает обязательных параметров, кук, заголовков и т.д. |
209 | | `INVALID_CLIENT` | redirect_uri не соответствует клиенту |
210 | | `INVALID_GRANT` | Передан невалидный (протухший) refresh_token или code |
211 | | `UNAUTHORIZED_CLIENT` | Нет заголовка |
212 | | `UNSUPPORTED_GRANT_TYPE` | Передан неизвестный grant_type |
213 | | `SERVER_ERROR` | Что-то пошло не так, возможно стоит перезапустить авторизационный диалог |
214 | | `LIMIT_EXCEEDED` | Приложению слишком часто запрашивает выпуск токенов (текущий лимит 50 в час), возможно, стоит поискать ошибку в приложении |
215 | | `UNKNOWN_ERROR` | Вернулся неизвестный тип ошибки |
216 |
217 | ## Example
218 |
219 | SDK поставляется с примером приложения, где можно посмотреть работу авторизации.
220 | В папке [app-demo](app-demo) содержится тестовое приложение.
221 | В данном приложении можно:
222 | - Проверить работу вашего clientId, подставив его в необходимое поле
223 | - Посмотреть варианты дизайна кнопки
224 | - Авторизоваться через приложение Тинькофф или WebView
225 | - Отозвать токены
226 | - Обновить токены
227 |
228 | Для авторизации так же требуется установить хотя бы одно из приложений Тинькофф.
229 |
230 | ## Поддержка
231 |
232 | - По возникающим вопросам просьба обращаться на Tinkoff_id@tinkoff.ru
233 | - Баги и feature-реквесты можно направлять в раздел [issues](https://github.com/tinkoff-mobile-tech/TinkoffID-Android/issues)
234 |
--------------------------------------------------------------------------------
/app-demo/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app-demo/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply from: rootProject.file('gradle/versions.gradle')
4 | apply from: rootProject.file('gradle/plugin/detekt.gradle')
5 |
6 | android {
7 | compileSdkVersion rootProject.ext.compileSdkVersion
8 |
9 | defaultConfig {
10 | multiDexEnabled = true
11 | minSdkVersion rootProject.minSdkVersion
12 | targetSdkVersion rootProject.targetSdkVersion
13 | versionCode rootProject.authCode
14 | versionName rootProject.authVersion
15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 | compileOptions {
25 | sourceCompatibility JavaVersion.VERSION_1_8
26 | targetCompatibility JavaVersion.VERSION_1_8
27 | }
28 |
29 | }
30 |
31 | dependencies {
32 | api project(':tinkoff-id')
33 | api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
34 | api "androidx.appcompat:appcompat:${appCompatVersion}"
35 | api "androidx.constraintlayout:constraintlayout:${constraintLayoutVersion}"
36 | api "com.google.android.material:material:${materialVersion}"
37 | //rx
38 | api "io.reactivex.rxjava2:rxjava:$rxJavaVersion"
39 | api "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion"
40 | //tests
41 | androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
42 | androidTestImplementation "androidx.test:rules:$testRuleVersion"
43 | androidTestImplementation "androidx.test.uiautomator:uiautomator:$uiautomatorVersion"
44 | }
45 |
--------------------------------------------------------------------------------
/app-demo/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-demo/src/androidTest/java/ru/tinkoff/core/app_demo_partner/TinkoffIdSignInButtonTest.kt:
--------------------------------------------------------------------------------
1 | package ru.tinkoff.core.app_demo_partner
2 |
3 | import androidx.test.espresso.Espresso.onView
4 | import androidx.test.espresso.assertion.ViewAssertions.matches
5 | import androidx.test.espresso.matcher.ViewMatchers
6 | import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
7 | import androidx.test.espresso.matcher.ViewMatchers.withChild
8 | import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
9 | import androidx.test.espresso.matcher.ViewMatchers.withId
10 | import androidx.test.espresso.matcher.ViewMatchers.withText
11 | import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
12 | import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
13 | import androidx.test.rule.ActivityTestRule
14 | import androidx.test.runner.AndroidJUnitRunner
15 | import org.hamcrest.CoreMatchers.allOf
16 | import org.junit.Before
17 | import org.junit.Rule
18 | import org.junit.Test
19 | import org.junit.runner.RunWith
20 | import ru.tinkoff.core.tinkoffId.ui.TinkoffIdSignInButton
21 |
22 | /**
23 | * @author k.voskrebentsev
24 | */
25 | @RunWith(AndroidJUnit4ClassRunner::class)
26 | class TinkoffIdSignInButtonTest : AndroidJUnitRunner() {
27 |
28 | @get:Rule
29 | val activityRule = ActivityTestRule(PartnerActivity::class.java, false, true)
30 |
31 | private lateinit var standardButton: TinkoffIdSignInButton
32 |
33 | @Before
34 | fun setUp() {
35 | runOnMainThread {
36 | standardButton = activityRule.activity.findViewById(standardButtonId)
37 | }
38 | }
39 |
40 | @Test
41 | fun testTitleChanging() {
42 | runOnMainThread {
43 | standardButton.title = SOME_TEXT
44 | }
45 |
46 | checkTextOnView(createFinalTitle(SOME_TEXT))
47 | }
48 |
49 | @Test
50 | fun testBadgeTextChanging() {
51 | runOnMainThread {
52 | standardButton.badgeText = SOME_TEXT
53 | }
54 |
55 | checkTextOnView(SOME_TEXT)
56 | }
57 |
58 | @Test
59 | fun testTextElementsHidingInCompactMode() {
60 | runOnMainThread {
61 | standardButton.title = SOME_TEXT
62 | standardButton.badgeText = SOME_TEXT
63 | standardButton.isCompact = true
64 | }
65 |
66 | onView(
67 | allOf(
68 | withId(standardButtonId),
69 | // title element
70 | withChild(
71 | allOf(
72 | withText(createFinalTitle(SOME_TEXT)),
73 | withEffectiveVisibility(ViewMatchers.Visibility.GONE)
74 | )
75 | ),
76 | // badge element
77 | withChild(
78 | allOf(
79 | withText(SOME_TEXT),
80 | withEffectiveVisibility(ViewMatchers.Visibility.GONE)
81 | )
82 | ),
83 | )
84 | ).check(matches(isDisplayed()))
85 | }
86 |
87 | private fun checkTextOnView(text: String) {
88 | onView(
89 | allOf(
90 | withId(standardButtonId),
91 | withChild(withText(text))
92 | )
93 | ).check(matches(isDisplayed()))
94 | }
95 |
96 | private fun createFinalTitle(titlePart: String) = "$titlePart $permanentTitlePart"
97 | private fun runOnMainThread(block: () -> Unit) {
98 | activityRule.runOnUiThread(block)
99 | }
100 |
101 | private companion object {
102 | private const val SOME_TEXT = "test"
103 |
104 | private const val standardButtonId = R.id.standardSmallBlackButtonTinkoffAuth
105 |
106 | private val permanentTitlePart = getInstrumentation().targetContext.resources.getString(ru.tinkoff.core.tinkoffId.R.string.tinkoff_id_tinkoff_text)
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/app-demo/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
18 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app-demo/src/main/java/ru/tinkoff/core/app_demo_partner/PartnerActivity.kt:
--------------------------------------------------------------------------------
1 | package ru.tinkoff.core.app_demo_partner
2 |
3 | import android.content.Intent
4 | import android.net.Uri
5 | import android.os.Bundle
6 | import android.view.View
7 | import android.widget.Button
8 | import android.widget.EditText
9 | import android.widget.Toast
10 | import androidx.appcompat.app.AppCompatActivity
11 | import ru.tinkoff.core.tinkoffId.TinkoffIdAuth
12 | import ru.tinkoff.core.tinkoffId.ui.TinkoffIdSignInButton
13 | import kotlin.LazyThreadSafetyMode.NONE
14 |
15 | class PartnerActivity : AppCompatActivity() {
16 |
17 | private val callbackUrl: Uri = Uri.Builder()
18 | .scheme("https")
19 | .authority("www.partner.com")
20 | .appendPath("partner")
21 | .build()
22 |
23 | private val redirectUri = "mobile://"
24 | private val clientId = "test-partner-mobile"
25 |
26 | private lateinit var tinkoffPartnerAuth: TinkoffIdAuth
27 |
28 | private val partnerPresenter by lazy(NONE) { PartnerPresenter(tinkoffPartnerAuth, this) }
29 | private val clientIdEditText by lazy(NONE) { findViewById(R.id.etClientId) }
30 | private val redirectUriEditText by lazy(NONE) { findViewById(R.id.etRedirectUri) }
31 |
32 | private val reset by lazy(NONE) { findViewById