├── AccountManagement
├── CrossAccounts.cs
├── AuthyAccount.cs
├── IAccountManagerService.cs
└── AuthorizePage.cs
├── iOS
├── Assets.xcassets
│ ├── Contents.json
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Entitlements.plist
├── Main.cs
├── AppDelegate.cs
├── app.config
├── packages.config
├── LaunchScreen.storyboard
├── Info.plist
└── Authy.iOS.csproj
├── Droid
├── Resources
│ ├── drawable
│ │ └── icon.png
│ ├── drawable-hdpi
│ │ └── icon.png
│ ├── drawable-xhdpi
│ │ └── icon.png
│ ├── drawable-xxhdpi
│ │ └── icon.png
│ ├── layout
│ │ ├── Toolbar.axml
│ │ └── Tabbar.axml
│ ├── values
│ │ └── styles.xml
│ └── AboutResources.txt
├── Properties
│ ├── AndroidManifest.xml
│ └── AssemblyInfo.cs
├── Assets
│ └── AboutAssets.txt
├── MainActivity.cs
├── app.config
├── packages.config
└── Authy.Droid.csproj
├── App.xaml
├── ProfilePage.xaml
├── app.config
├── .gitignore
├── App.xaml.cs
├── ProfilePage.xaml.cs
├── AuthyPage.xaml
├── Authy.Shared
├── Authy.Shared.projitems
├── Authy.Shared.shproj
└── AccountManagement
│ ├── AccountManagementImplementation.cs
│ └── AuthorizePageRenderer.cs
├── packages.config
├── Properties
└── AssemblyInfo.cs
├── LoggingHandler.cs
├── Keys.cs
├── Authy.sln
├── Authy.csproj
└── AuthyPage.xaml.cs
/AccountManagement/CrossAccounts.cs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/iOS/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Droid/Resources/drawable/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thatcsharpguy/Authy/master/Droid/Resources/drawable/icon.png
--------------------------------------------------------------------------------
/Droid/Resources/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thatcsharpguy/Authy/master/Droid/Resources/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/Droid/Resources/drawable-xhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thatcsharpguy/Authy/master/Droid/Resources/drawable-xhdpi/icon.png
--------------------------------------------------------------------------------
/Droid/Resources/drawable-xxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thatcsharpguy/Authy/master/Droid/Resources/drawable-xxhdpi/icon.png
--------------------------------------------------------------------------------
/App.xaml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/AccountManagement/AuthyAccount.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | namespace Authy.AccountManagement
3 | {
4 | public class AuthyAccount
5 | {
6 | string _value;
7 | public AuthyAccount(string sth)
8 | {
9 | _value = sth;
10 | }
11 |
12 | public override string ToString()
13 | {
14 | return _value;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Droid/Properties/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/iOS/Entitlements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | keychain-access-groups
6 |
7 | com.thatcsharpguy.authy
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ProfilePage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/AccountManagement/IAccountManagerService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Authy.AccountManagement
5 | {
6 | public interface IAccountManagerService
7 | {
8 |
9 | List Accounts { get; }
10 |
11 | string GetPropertyFromAccount(Services service, string property);
12 |
13 | void EraseAll();
14 |
15 | }
16 |
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/Droid/Resources/layout/Toolbar.axml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/AccountManagement/AuthorizePage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xamarin.Forms;
3 |
4 | namespace Authy.AccountManagement
5 | {
6 | public enum Services
7 | {
8 | GitHub,
9 | Facebook,
10 | Twitter,
11 | //
12 | }
13 |
14 | public class AuthorizePage : ContentPage
15 | {
16 | public Services Service { get; private set; }
17 |
18 | public AuthorizePage(Services service)
19 | {
20 | Service = service;
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Droid/Resources/layout/Tabbar.axml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/iOS/Main.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using Foundation;
6 | using UIKit;
7 |
8 | namespace Authy.iOS
9 | {
10 | public class Application
11 | {
12 | // This is the main entry point of the application.
13 | static void Main(string[] args)
14 | {
15 | // if you want to use a different Application Delegate class from "AppDelegate"
16 | // you can specify it here.
17 | UIApplication.Main(args, null, "AppDelegate");
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Autosave files
2 | *~
3 |
4 | # build
5 | [Oo]bj/
6 | [Bb]in/
7 | packages/
8 | Components/
9 | TestResults/
10 |
11 | # globs
12 | Makefile.in
13 | *.DS_Store
14 | *.sln.cache
15 | *.suo
16 | *.cache
17 | *.pidb
18 | *.userprefs
19 | *.usertasks
20 | config.log
21 | config.make
22 | config.status
23 | aclocal.m4
24 | install-sh
25 | autom4te.cache/
26 | *.user
27 | *.tar.gz
28 | tarballs/
29 | test-results/
30 | Thumbs.db
31 |
32 | # Mac bundle stuff
33 | *.dmg
34 | *.app
35 |
36 | # resharper
37 | *_Resharper.*
38 | *.Resharper
39 |
40 | # dotCover
41 | *.dotCover
42 |
--------------------------------------------------------------------------------
/iOS/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using Authy.iOS.AccountManagement;
5 | using Foundation;
6 | using UIKit;
7 |
8 | namespace Authy.iOS
9 | {
10 | [Register("AppDelegate")]
11 | public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
12 | {
13 | public override bool FinishedLaunching(UIApplication app, NSDictionary options)
14 | {
15 | global::Xamarin.Forms.Forms.Init();
16 | AccountManagementImplementation.Init();
17 |
18 | LoadApplication(new App());
19 |
20 | return base.FinishedLaunching(app, options);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Droid/Assets/AboutAssets.txt:
--------------------------------------------------------------------------------
1 | Any raw assets you want to be deployed with your application can be placed in
2 | this directory (and child directories) and given a Build Action of "AndroidAsset".
3 |
4 | These files will be deployed with your package and will be accessible using Android's
5 | AssetManager, like this:
6 |
7 | public class ReadAsset : Activity
8 | {
9 | protected override void OnCreate (Bundle bundle)
10 | {
11 | base.OnCreate (bundle);
12 |
13 | InputStream input = Assets.Open ("my_asset.txt");
14 | }
15 | }
16 |
17 | Additionally, some Android functions will automatically load asset files:
18 |
19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");
20 |
--------------------------------------------------------------------------------
/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xamarin.Forms;
3 |
4 | using Authy.AccountManagement;
5 |
6 | namespace Authy
7 | {
8 | public partial class App : Application
9 | {
10 | public App()
11 | {
12 | InitializeComponent();
13 |
14 | IsLogged = false;
15 |
16 | MainPage = new NavigationPage(new AuthyPage());
17 | }
18 |
19 | public static bool IsLogged;
20 |
21 | public const string AppName = "Authy";
22 |
23 | protected override void OnStart()
24 | {
25 | // Handle when your app starts
26 | }
27 |
28 | protected override void OnSleep()
29 | {
30 | // Handle when your app sleeps
31 | }
32 |
33 | protected override void OnResume()
34 | {
35 | // Handle when your app resumes
36 | }
37 |
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/ProfilePage.xaml.cs:
--------------------------------------------------------------------------------
1 | using Authy.AccountManagement;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | using Xamarin.Forms;
9 |
10 | namespace Authy
11 | {
12 | public partial class ProfilePage : ContentPage
13 | {
14 | public ProfilePage(Services service)
15 | {
16 | InitializeComponent();
17 | Title = service.ToString();
18 | }
19 |
20 |
21 | public ProfilePage(Services service, string name, string image)
22 | {
23 | InitializeComponent();
24 | Title = service.ToString();
25 | ProfileImage.Source = image;
26 | LoginName.Text = name;
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/AuthyPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
22 |
23 |
27 |
28 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Authy.Shared/Authy.Shared.projitems:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
5 | true
6 | {A10FA724-8CC4-49D7-9EA9-B21EA43E671A}
7 |
8 |
9 | Authy.Shared
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Droid/MainActivity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using Android.App;
4 | using Android.Content;
5 | using Android.Content.PM;
6 | using Android.Runtime;
7 | using Android.Views;
8 | using Android.Widget;
9 | using Android.OS;
10 | using Authy.Droid.AccountManagement;
11 |
12 | namespace Authy.Droid
13 | {
14 | [Activity(Label = "Authy.Droid", Icon = "@drawable/icon", Theme = "@style/MyTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
15 | public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
16 | {
17 | protected override void OnCreate(Bundle bundle)
18 | {
19 | TabLayoutResource = Resource.Layout.Tabbar;
20 | ToolbarResource = Resource.Layout.Toolbar;
21 |
22 | base.OnCreate(bundle);
23 |
24 | global::Xamarin.Forms.Forms.Init(this, bundle);
25 | AccountManagementImplementation.Init();
26 |
27 | LoadApplication(new App());
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Droid/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/iOS/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Authy.Shared/Authy.Shared.shproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {A10FA724-8CC4-49D7-9EA9-B21EA43E671A}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/iOS/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 |
4 | // Information about this assembly is defined by the following attributes.
5 | // Change them to the values specific to your project.
6 |
7 | [assembly: AssemblyTitle("Authy")]
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("")]
11 | [assembly: AssemblyProduct("")]
12 | [assembly: AssemblyCopyright("fferegrino")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision,
18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision.
19 |
20 | [assembly: AssemblyVersion("1.0.*")]
21 |
22 | // The following attributes are used to specify the signing key for the assembly,
23 | // if desired. See the Mono documentation for more information about signing.
24 |
25 | //[assembly: AssemblyDelaySign(false)]
26 | //[assembly: AssemblyKeyFile("")]
27 |
--------------------------------------------------------------------------------
/Droid/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using Android.App;
4 |
5 | // Information about this assembly is defined by the following attributes.
6 | // Change them to the values specific to your project.
7 |
8 | [assembly: AssemblyTitle("Authy.Droid")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("")]
13 | [assembly: AssemblyCopyright("fferegrino")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
18 | // The form "{Major}.{Minor}.*" will automatically update the build and revision,
19 | // and "{Major}.{Minor}.{Build}.*" will update just the revision.
20 |
21 | [assembly: AssemblyVersion("1.0.0")]
22 |
23 | // The following attributes are used to specify the signing key for the assembly,
24 | // if desired. See the Mono documentation for more information about signing.
25 |
26 | //[assembly: AssemblyDelaySign(false)]
27 | //[assembly: AssemblyKeyFile("")]
28 |
--------------------------------------------------------------------------------
/LoggingHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net.Http;
5 | using System.Text;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 | using Console = System.Diagnostics.Debug;
9 |
10 | namespace Authy
11 | {
12 | class LoggingHandler : DelegatingHandler
13 | {
14 | public LoggingHandler(HttpMessageHandler innerHandler)
15 | : base(innerHandler)
16 | {
17 | }
18 |
19 |
20 | protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
21 | {
22 | Console.WriteLine("Request:");
23 | Console.WriteLine(request.ToString());
24 | if (request.Content != null)
25 | {
26 | Console.WriteLine(await request.Content.ReadAsStringAsync());
27 | }
28 | Console.WriteLine("");
29 |
30 | HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
31 |
32 | Console.WriteLine("Response:");
33 | Console.WriteLine(response.ToString());
34 | if (response.Content != null)
35 | {
36 | Console.WriteLine(await response.Content.ReadAsStringAsync());
37 | }
38 | Console.WriteLine("");
39 |
40 | return response;
41 | }
42 | }
43 |
44 | }
--------------------------------------------------------------------------------
/Droid/Resources/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
24 |
27 |
28 |
--------------------------------------------------------------------------------
/iOS/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDisplayName
6 | Authy
7 | CFBundleName
8 | Authy
9 | CFBundleIdentifier
10 | com.thatcsharpguy.authy
11 | CFBundleShortVersionString
12 | 1.0
13 | CFBundleVersion
14 | 1.0
15 | LSRequiresIPhoneOS
16 |
17 | MinimumOSVersion
18 | 8.0
19 | UIDeviceFamily
20 |
21 | 1
22 | 2
23 |
24 | UILaunchStoryboardName
25 | LaunchScreen
26 | UIRequiredDeviceCapabilities
27 |
28 | armv7
29 |
30 | UISupportedInterfaceOrientations
31 |
32 | UIInterfaceOrientationPortrait
33 | UIInterfaceOrientationLandscapeLeft
34 | UIInterfaceOrientationLandscapeRight
35 |
36 | UISupportedInterfaceOrientations~ipad
37 |
38 | UIInterfaceOrientationPortrait
39 | UIInterfaceOrientationPortraitUpsideDown
40 | UIInterfaceOrientationLandscapeLeft
41 | UIInterfaceOrientationLandscapeRight
42 |
43 | XSAppIconAssets
44 | Assets.xcassets/AppIcon.appiconset
45 |
46 |
47 |
--------------------------------------------------------------------------------
/Droid/Resources/AboutResources.txt:
--------------------------------------------------------------------------------
1 | Images, layout descriptions, binary blobs and string dictionaries can be included
2 | in your application as resource files. Various Android APIs are designed to
3 | operate on the resource IDs instead of dealing with images, strings or binary blobs
4 | directly.
5 |
6 | For example, a sample Android app that contains a user interface layout (main.axml),
7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
8 | would keep its resources in the "Resources" directory of the application:
9 |
10 | Resources/
11 | drawable/
12 | icon.png
13 |
14 | layout/
15 | main.axml
16 |
17 | values/
18 | strings.xml
19 |
20 | In order to get the build system to recognize Android resources, set the build action to
21 | "AndroidResource". The native Android APIs do not operate directly with filenames, but
22 | instead operate on resource IDs. When you compile an Android application that uses resources,
23 | the build system will package the resources for distribution and generate a class called "R"
24 | (this is an Android convention) that contains the tokens for each one of the resources
25 | included. For example, for the above Resources layout, this is what the R class would expose:
26 |
27 | public class R {
28 | public class drawable {
29 | public const int icon = 0x123;
30 | }
31 |
32 | public class layout {
33 | public const int main = 0x456;
34 | }
35 |
36 | public class strings {
37 | public const int first_string = 0xabc;
38 | public const int second_string = 0xbcd;
39 | }
40 | }
41 |
42 | You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main
43 | to reference the layout/main.axml file, or R.strings.first_string to reference the first
44 | string in the dictionary file values/strings.xml.
45 |
--------------------------------------------------------------------------------
/Authy.Shared/AccountManagement/AccountManagementImplementation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Collections.Generic;
4 | using Authy.AccountManagement;
5 |
6 | #if __IOS__
7 | [assembly: Xamarin.Forms.Dependency(typeof(Authy.iOS.AccountManagement.AccountManagementImplementation))]
8 | namespace Authy.iOS.AccountManagement
9 | #elif __ANDROID__
10 | [assembly: Xamarin.Forms.Dependency(typeof(Authy.Droid.AccountManagement.AccountManagementImplementation))]
11 | namespace Authy.Droid.AccountManagement
12 | #endif
13 | {
14 | public class AccountManagementImplementation : IAccountManagerService
15 | {
16 | public static void Init() { var now = DateTime.Now; }
17 |
18 | public List Accounts
19 | {
20 | get
21 | {
22 | var accounts = new List();
23 | var accountStore = Xamarin.Auth.AccountStore.Create();
24 | foreach (var service in Enum.GetNames(typeof(Services)))
25 | {
26 | var acc = accountStore.FindAccountsForService(service).FirstOrDefault();
27 | if (acc != null)
28 | {
29 | accounts.Add((Services)Enum.Parse(typeof(Services), service));
30 | }
31 | }
32 | return accounts;
33 | }
34 | }
35 |
36 | public void EraseAll()
37 | {
38 | var accountStore = Xamarin.Auth.AccountStore.Create();
39 | foreach (var service in Enum.GetNames(typeof(Services)))
40 | {
41 | var acc = accountStore.FindAccountsForService(service).FirstOrDefault();
42 | if (acc != null)
43 | {
44 | accountStore.Delete(acc, service);
45 | }
46 | }
47 | }
48 |
49 | public string GetPropertyFromAccount(Services service, string property)
50 | {
51 | var accountStore = Xamarin.Auth.AccountStore.Create();
52 | var account = accountStore.FindAccountsForService(service.ToString()).FirstOrDefault();
53 | if (account != null)
54 | {
55 | return account.Properties[property];
56 | }
57 | return null;
58 | }
59 | }
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/Droid/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Keys.cs:
--------------------------------------------------------------------------------
1 | namespace Authy
2 | {
3 | public interface IKeys
4 | {
5 | string ClientId { get; }
6 | string ClientSecret { get; }
7 | string Scope { get; }
8 | string AuthorizeUrl { get; }
9 | string RedirectUrl { get; }
10 | string RequestTokenUrl { get; }
11 | string AccessTokenUrl { get; }
12 | string ConsumerSecret { get; }
13 | string ConsumerKey { get; }
14 | string CallbackUrl { get; }
15 | }
16 |
17 | public class FacebookKeys : IKeys
18 | {
19 |
20 | public string ClientId { get; } = "";
21 |
22 | public string AuthorizeUrl { get; } = "https://m.facebook.com/dialog/oauth/";
23 |
24 | public string RedirectUrl { get; } = "https://www.facebook.com/connect/login_success.html";
25 |
26 | public string AccessTokenUrl { get; } = "";
27 |
28 | public string ClientSecret { get; }
29 |
30 | public string ConsumerKey { get; }
31 |
32 | public string ConsumerSecret { get; }
33 |
34 | public string RequestTokenUrl { get; }
35 |
36 | public string Scope { get; }
37 |
38 | public string CallbackUrl { get; }
39 | }
40 |
41 | public class GitHubKeys : IKeys
42 | {
43 |
44 | public string ClientId => "";
45 |
46 | public string ClientSecret => "";
47 |
48 | public string AccessTokenUrl { get; } = "https://github.com/login/oauth/access_token";
49 |
50 | public string AuthorizeUrl { get; } = "https://github.com/login/oauth/authorize";
51 |
52 | public string RedirectUrl { get; } = "https://github.com";
53 |
54 | public string ConsumerKey { get; }
55 |
56 | public string ConsumerSecret { get; }
57 |
58 |
59 | public string RequestTokenUrl { get; }
60 |
61 | public string Scope { get; }
62 |
63 | public string CallbackUrl { get; }
64 | }
65 |
66 | public class TwitterKeys : IKeys
67 | {
68 |
69 | public string ConsumerKey { get; } = "";
70 |
71 | public string ConsumerSecret => "";
72 |
73 | public string AccessTokenUrl { get; } = "https://api.twitter.com/oauth/access_token";
74 |
75 | public string AuthorizeUrl { get; } = "https://api.twitter.com/oauth/authorize";
76 |
77 | public string RedirectUrl { get; } = "https://mobile.twitter.com/home";
78 |
79 | public string RequestTokenUrl => "https://api.twitter.com/oauth/request_token";
80 |
81 | public string CallbackUrl => "https://mobile.twitter.com/home";
82 |
83 | public string ClientId { get; } = "";
84 |
85 | public string ClientSecret { get; } = "";
86 |
87 | public string Scope { get; } = "";
88 |
89 |
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "idiom": "iphone",
5 | "size": "29x29",
6 | "scale": "1x"
7 | },
8 | {
9 | "idiom": "iphone",
10 | "size": "29x29",
11 | "scale": "2x"
12 | },
13 | {
14 | "idiom": "iphone",
15 | "size": "29x29",
16 | "scale": "3x"
17 | },
18 | {
19 | "idiom": "iphone",
20 | "size": "40x40",
21 | "scale": "2x"
22 | },
23 | {
24 | "idiom": "iphone",
25 | "size": "40x40",
26 | "scale": "3x"
27 | },
28 | {
29 | "idiom": "iphone",
30 | "size": "57x57",
31 | "scale": "1x"
32 | },
33 | {
34 | "idiom": "iphone",
35 | "size": "57x57",
36 | "scale": "2x"
37 | },
38 | {
39 | "idiom": "iphone",
40 | "size": "60x60",
41 | "scale": "2x"
42 | },
43 | {
44 | "idiom": "iphone",
45 | "size": "60x60",
46 | "scale": "3x"
47 | },
48 | {
49 | "idiom": "ipad",
50 | "size": "29x29",
51 | "scale": "1x"
52 | },
53 | {
54 | "idiom": "ipad",
55 | "size": "29x29",
56 | "scale": "2x"
57 | },
58 | {
59 | "idiom": "ipad",
60 | "size": "40x40",
61 | "scale": "1x"
62 | },
63 | {
64 | "idiom": "ipad",
65 | "size": "40x40",
66 | "scale": "2x"
67 | },
68 | {
69 | "idiom": "ipad",
70 | "size": "50x50",
71 | "scale": "1x"
72 | },
73 | {
74 | "idiom": "ipad",
75 | "size": "50x50",
76 | "scale": "2x"
77 | },
78 | {
79 | "idiom": "ipad",
80 | "size": "72x72",
81 | "scale": "1x"
82 | },
83 | {
84 | "idiom": "ipad",
85 | "size": "72x72",
86 | "scale": "2x"
87 | },
88 | {
89 | "idiom": "ipad",
90 | "size": "76x76",
91 | "scale": "1x"
92 | },
93 | {
94 | "idiom": "ipad",
95 | "size": "76x76",
96 | "scale": "2x"
97 | },
98 | {
99 | "size": "24x24",
100 | "idiom": "watch",
101 | "scale": "2x",
102 | "role": "notificationCenter",
103 | "subtype": "38mm"
104 | },
105 | {
106 | "size": "27.5x27.5",
107 | "idiom": "watch",
108 | "scale": "2x",
109 | "role": "notificationCenter",
110 | "subtype": "42mm"
111 | },
112 | {
113 | "size": "29x29",
114 | "idiom": "watch",
115 | "role": "companionSettings",
116 | "scale": "2x"
117 | },
118 | {
119 | "size": "29x29",
120 | "idiom": "watch",
121 | "role": "companionSettings",
122 | "scale": "3x"
123 | },
124 | {
125 | "size": "40x40",
126 | "idiom": "watch",
127 | "scale": "2x",
128 | "role": "appLauncher",
129 | "subtype": "38mm"
130 | },
131 | {
132 | "size": "44x44",
133 | "idiom": "watch",
134 | "scale": "2x",
135 | "role": "longLook",
136 | "subtype": "42mm"
137 | },
138 | {
139 | "size": "86x86",
140 | "idiom": "watch",
141 | "scale": "2x",
142 | "role": "quickLook",
143 | "subtype": "38mm"
144 | },
145 | {
146 | "size": "98x98",
147 | "idiom": "watch",
148 | "scale": "2x",
149 | "role": "quickLook",
150 | "subtype": "42mm"
151 | }
152 | ],
153 | "info": {
154 | "version": 1,
155 | "author": "xcode"
156 | }
157 | }
--------------------------------------------------------------------------------
/Authy.Shared/AccountManagement/AuthorizePageRenderer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Authy.AccountManagement;
3 | using Xamarin.Forms;
4 | using Xamarin.Auth;
5 | #if __IOS__
6 | using Xamarin.Forms.Platform.iOS;
7 | #elif __ANDROID__
8 | using Xamarin.Forms.Platform.Android;
9 | #endif
10 |
11 | #if __IOS__
12 | [assembly: ExportRenderer(typeof(AuthorizePage), typeof(Authy.iOS.AccountManagement.AuthorizePageRenderer))]
13 | namespace Authy.iOS.AccountManagement
14 | #elif __ANDROID__
15 | [assembly: ExportRenderer(typeof(AuthorizePage), typeof(Authy.Droid.AccountManagement.AuthorizePageRenderer))]
16 | namespace Authy.Droid.AccountManagement
17 | #endif
18 | {
19 | public class AuthorizePageRenderer : PageRenderer
20 | {
21 |
22 | #if __IOS__
23 | public override void ViewDidAppear(bool animated)
24 | {
25 | base.ViewDidAppear(animated);
26 | #elif __ANDROID__
27 | protected override void OnElementChanged(ElementChangedEventArgs e)
28 | {
29 | base.OnElementChanged(e);
30 | var activity = this.Context as Android.App.Activity;
31 | #endif
32 |
33 |
34 | OAuth2Authenticator auth2 = null;
35 | OAuth1Authenticator auth1 = null;
36 | IKeys keys = null;
37 |
38 | var authPage = Element as AuthorizePage;
39 |
40 | switch (authPage.Service)
41 | {
42 | case Services.Facebook:
43 | keys = new FacebookKeys();
44 | auth2 = new OAuth2Authenticator(
45 | clientId: keys.ClientId,
46 | scope: keys.Scope,
47 | authorizeUrl: new Uri(keys.AuthorizeUrl),
48 | redirectUrl: new Uri(keys.RedirectUrl));
49 | break;
50 | case Services.Twitter:
51 | keys = new TwitterKeys();
52 | auth1 = new OAuth1Authenticator(
53 | consumerKey: keys.ConsumerKey,
54 | consumerSecret: keys.ConsumerSecret,
55 | requestTokenUrl: new Uri(keys.RequestTokenUrl),
56 | authorizeUrl: new Uri(keys.AuthorizeUrl),
57 | accessTokenUrl: new Uri(keys.AccessTokenUrl),
58 | callbackUrl: new Uri(keys.CallbackUrl));
59 | break;
60 | case Services.GitHub:
61 | keys = new GitHubKeys();
62 | auth2 = new OAuth2Authenticator(
63 | clientId: keys.ClientId,
64 | clientSecret: keys.ClientSecret,
65 | scope: keys.Scope,
66 | authorizeUrl: new Uri(keys.AuthorizeUrl),
67 | redirectUrl: new Uri(keys.RedirectUrl),
68 | accessTokenUrl: new Uri(keys.AccessTokenUrl));
69 | break;
70 | default:
71 | throw new Exception("Service " + authPage.Service + " not yet supported");
72 | }
73 |
74 | if (auth2 != null)
75 | {
76 | auth2.Completed += async (sender, eventArgs) =>
77 | {
78 | #if __IOS__
79 | DismissViewController(true, null);
80 | #endif
81 | if (eventArgs.IsAuthenticated)
82 | AccountStore.Create().Save(eventArgs.Account, authPage.Service.ToString());
83 | await authPage.Navigation.PopAsync();
84 | };
85 | #if __IOS__
86 | PresentViewController(auth2.GetUI(), true, null);
87 | #elif __ANDROID__
88 | activity.StartActivity(auth2.GetUI(activity));
89 | #endif
90 | }
91 |
92 | if (auth1 != null)
93 | {
94 | auth1.Completed += async (sender, eventArgs) =>
95 | {
96 | #if __IOS__
97 | DismissViewController(true, null);
98 | #endif
99 | if (eventArgs.IsAuthenticated)
100 | AccountStore.Create().Save(eventArgs.Account, authPage.Service.ToString());
101 | await authPage.Navigation.PopAsync();
102 | };
103 |
104 | #if __IOS__
105 | PresentViewController(auth1.GetUI(), true, null);
106 | #elif __ANDROID__
107 | activity.StartActivity(auth1.GetUI(activity));
108 | #endif
109 | }
110 |
111 | }
112 | }
113 |
114 | }
--------------------------------------------------------------------------------
/Authy.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 14
3 | VisualStudioVersion = 14.0.25420.1
4 | MinimumVisualStudioVersion = 10.0.40219.1
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Authy", "Authy.csproj", "{61651E76-AA7A-4C37-AC6B-56D66B8BCFAE}"
6 | EndProject
7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Authy.iOS", "iOS\Authy.iOS.csproj", "{2BF68393-14DC-4139-8DA1-29CE597F3579}"
8 | EndProject
9 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Authy.Droid", "Droid\Authy.Droid.csproj", "{2BA34DCF-7286-4C53-8A8B-B190E04A48C6}"
10 | EndProject
11 | Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Authy.Shared", "Authy.Shared\Authy.Shared.shproj", "{A10FA724-8CC4-49D7-9EA9-B21EA43E671A}"
12 | EndProject
13 | Global
14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
15 | Debug|Any CPU = Debug|Any CPU
16 | Debug|iPhone = Debug|iPhone
17 | Debug|iPhoneSimulator = Debug|iPhoneSimulator
18 | Release|Any CPU = Release|Any CPU
19 | Release|iPhone = Release|iPhone
20 | Release|iPhoneSimulator = Release|iPhoneSimulator
21 | EndGlobalSection
22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
23 | {61651E76-AA7A-4C37-AC6B-56D66B8BCFAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
24 | {61651E76-AA7A-4C37-AC6B-56D66B8BCFAE}.Debug|Any CPU.Build.0 = Debug|Any CPU
25 | {61651E76-AA7A-4C37-AC6B-56D66B8BCFAE}.Debug|iPhone.ActiveCfg = Debug|Any CPU
26 | {61651E76-AA7A-4C37-AC6B-56D66B8BCFAE}.Debug|iPhone.Build.0 = Debug|Any CPU
27 | {61651E76-AA7A-4C37-AC6B-56D66B8BCFAE}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
28 | {61651E76-AA7A-4C37-AC6B-56D66B8BCFAE}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
29 | {61651E76-AA7A-4C37-AC6B-56D66B8BCFAE}.Release|Any CPU.ActiveCfg = Release|Any CPU
30 | {61651E76-AA7A-4C37-AC6B-56D66B8BCFAE}.Release|Any CPU.Build.0 = Release|Any CPU
31 | {61651E76-AA7A-4C37-AC6B-56D66B8BCFAE}.Release|iPhone.ActiveCfg = Release|Any CPU
32 | {61651E76-AA7A-4C37-AC6B-56D66B8BCFAE}.Release|iPhone.Build.0 = Release|Any CPU
33 | {61651E76-AA7A-4C37-AC6B-56D66B8BCFAE}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
34 | {61651E76-AA7A-4C37-AC6B-56D66B8BCFAE}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
35 | {2BF68393-14DC-4139-8DA1-29CE597F3579}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator
36 | {2BF68393-14DC-4139-8DA1-29CE597F3579}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator
37 | {2BF68393-14DC-4139-8DA1-29CE597F3579}.Debug|iPhone.ActiveCfg = Debug|iPhone
38 | {2BF68393-14DC-4139-8DA1-29CE597F3579}.Debug|iPhone.Build.0 = Debug|iPhone
39 | {2BF68393-14DC-4139-8DA1-29CE597F3579}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
40 | {2BF68393-14DC-4139-8DA1-29CE597F3579}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
41 | {2BF68393-14DC-4139-8DA1-29CE597F3579}.Release|Any CPU.ActiveCfg = Release|iPhone
42 | {2BF68393-14DC-4139-8DA1-29CE597F3579}.Release|Any CPU.Build.0 = Release|iPhone
43 | {2BF68393-14DC-4139-8DA1-29CE597F3579}.Release|iPhone.ActiveCfg = Release|iPhone
44 | {2BF68393-14DC-4139-8DA1-29CE597F3579}.Release|iPhone.Build.0 = Release|iPhone
45 | {2BF68393-14DC-4139-8DA1-29CE597F3579}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
46 | {2BF68393-14DC-4139-8DA1-29CE597F3579}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
47 | {2BA34DCF-7286-4C53-8A8B-B190E04A48C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
48 | {2BA34DCF-7286-4C53-8A8B-B190E04A48C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
49 | {2BA34DCF-7286-4C53-8A8B-B190E04A48C6}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
50 | {2BA34DCF-7286-4C53-8A8B-B190E04A48C6}.Debug|iPhone.ActiveCfg = Debug|Any CPU
51 | {2BA34DCF-7286-4C53-8A8B-B190E04A48C6}.Debug|iPhone.Build.0 = Debug|Any CPU
52 | {2BA34DCF-7286-4C53-8A8B-B190E04A48C6}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
53 | {2BA34DCF-7286-4C53-8A8B-B190E04A48C6}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
54 | {2BA34DCF-7286-4C53-8A8B-B190E04A48C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
55 | {2BA34DCF-7286-4C53-8A8B-B190E04A48C6}.Release|Any CPU.Build.0 = Release|Any CPU
56 | {2BA34DCF-7286-4C53-8A8B-B190E04A48C6}.Release|iPhone.ActiveCfg = Release|Any CPU
57 | {2BA34DCF-7286-4C53-8A8B-B190E04A48C6}.Release|iPhone.Build.0 = Release|Any CPU
58 | {2BA34DCF-7286-4C53-8A8B-B190E04A48C6}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
59 | {2BA34DCF-7286-4C53-8A8B-B190E04A48C6}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
60 | EndGlobalSection
61 | GlobalSection(SolutionProperties) = preSolution
62 | HideSolutionNode = FALSE
63 | EndGlobalSection
64 | EndGlobal
65 |
--------------------------------------------------------------------------------
/Authy.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | {61651E76-AA7A-4C37-AC6B-56D66B8BCFAE}
7 | {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
8 | true
9 | Library
10 | Authy
11 | Authy
12 | v4.5
13 | Profile259
14 |
15 |
16 |
17 |
18 | true
19 | full
20 | false
21 | bin\Debug
22 | DEBUG;
23 | prompt
24 | 4
25 |
26 |
27 | true
28 | bin\Release
29 | prompt
30 | 4
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | App.xaml
39 |
40 |
41 | AuthyPage.xaml
42 |
43 |
44 |
45 | ProfilePage.xaml
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | packages\modernhttpclient.2.4.2\lib\Portable-Net45+WinRT45+WP8+WPA81\ModernHttpClient.dll
56 | True
57 |
58 |
59 | packages\Newtonsoft.Json.9.0.1\lib\portable-net45+wp80+win8+wpa81\Newtonsoft.Json.dll
60 | True
61 |
62 |
63 | packages\Microsoft.Net.Http.2.2.29\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.dll
64 | True
65 |
66 |
67 | packages\Microsoft.Net.Http.2.2.29\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.Extensions.dll
68 | True
69 |
70 |
71 | packages\Microsoft.Net.Http.2.2.29\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.Primitives.dll
72 | True
73 |
74 |
75 | packages\Xamarin.Forms.2.3.2.127\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Core.dll
76 |
77 |
78 | packages\Xamarin.Forms.2.3.2.127\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Platform.dll
79 |
80 |
81 | packages\Xamarin.Forms.2.3.2.127\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Xaml.dll
82 |
83 |
84 | packages\Validation.2.0.4.14103\lib\portable-windows8+net40+sl5+wp8+wpa81+wp81+MonoAndroid+MonoTouch\Validation.dll
85 |
86 |
87 | packages\PCLCrypto.0.5.0.14108\lib\portable-net40+sl50+win+wpa81+wp80\PCLCrypto.Abstractions.dll
88 |
89 |
90 | packages\PCLCrypto.0.5.0.14108\lib\portable-net40+sl50+win+wpa81+wp80\PCLCrypto.dll
91 |
92 |
93 | packages\Xamarin.Auth.1.3.1.1\lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+XamarinIOS10\Xamarin.Auth.dll
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 | MSBuild:UpdateDesignTimeXaml
103 | Designer
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/AuthyPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using Authy.AccountManagement;
3 | using Xamarin.Auth;
4 | using Xamarin.Forms;
5 | using ModernHttpClient;
6 | using System.Net.Http;
7 | using System;
8 | using System.Collections.Generic;
9 | using Newtonsoft.Json;
10 | using Newtonsoft.Json.Linq;
11 | using System.Text;
12 | using PCLCrypto;
13 | using System.Threading.Tasks;
14 |
15 | namespace Authy
16 | {
17 | public partial class AuthyPage : ContentPage
18 | {
19 | IAccountManagerService _services;
20 | public AuthyPage()
21 | {
22 | InitializeComponent();
23 | Title = "Conectar cuentas";
24 |
25 | var deleteButton = new ToolbarItem { Text = "Delete" };
26 | deleteButton.Clicked += (s, a) =>
27 | {
28 | _services.EraseAll();
29 | };
30 |
31 | ToolbarItems.Add(deleteButton);
32 |
33 | _services = DependencyService.Get();
34 |
35 | facebook.Clicked += ViewProfileButton_Clicked;
36 | github.Clicked += ViewProfileButton_Clicked;
37 | twitter.Clicked += ViewProfileButton_Clicked;
38 | }
39 |
40 | async void ViewProfileButton_Clicked(object sender, System.EventArgs e)
41 | {
42 | var sndr = sender as Button;
43 |
44 | var accounts = _services.Accounts;
45 |
46 | #if DEBUG
47 | var httpClient = new HttpClient(new LoggingHandler(new HttpClientHandler()));
48 | #else
49 | var httpClient = new HttpClient(new NativeMessageHandler());
50 | #endif
51 |
52 | if (sndr == facebook)
53 | {
54 | if (accounts.Contains(Services.Facebook))
55 | {
56 | await ViewFacebookProfile(httpClient);
57 | }
58 | else
59 | {
60 | await Navigation.PushAsync(new AuthorizePage(Services.Facebook));
61 | }
62 | }
63 | else if (sndr == twitter)
64 | {
65 | if (accounts.Contains(Services.Twitter))
66 | {
67 | await ViewTwitterProfile(httpClient);
68 | }
69 | else
70 | {
71 | await Navigation.PushAsync(new AuthorizePage(Services.Twitter));
72 | }
73 | }
74 | else if (sndr == github)
75 | {
76 | if (accounts.Contains(Services.GitHub))
77 | {
78 | await ViewGitHubProfile(httpClient);
79 | }
80 | else
81 | {
82 | await Navigation.PushAsync(new AuthorizePage(Services.GitHub));
83 | }
84 | }
85 | else
86 | {
87 |
88 | }
89 | }
90 |
91 | async Task ViewGitHubProfile(HttpClient httpClient)
92 | {
93 | var uri = new Uri("https://api.github.com/user");
94 | var access_token = _services.GetPropertyFromAccount(Services.GitHub, "access_token");
95 |
96 | httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("token", access_token);
97 | httpClient.DefaultRequestHeaders.Add("User-Agent",
98 | "AB");
99 | var response = await httpClient.GetAsync(uri);
100 | if (response.IsSuccessStatusCode)
101 | {
102 | var content = await response.Content.ReadAsStringAsync();
103 | var a = (JObject)JsonConvert.DeserializeObject(content);
104 |
105 | var login = a["login"];
106 | var image = a["avatar_url"];
107 | await Navigation.PushAsync(new ProfilePage(Services.GitHub, login.ToString(), image.ToString()));
108 | }
109 | }
110 |
111 | async Task ViewFacebookProfile(HttpClient httpClient)
112 | {
113 | var access_token = _services.GetPropertyFromAccount(Services.Facebook, "access_token");
114 | var fbUri = new Uri("https://graph.facebook.com/me?access_token=" + access_token);
115 |
116 | httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("token", access_token);
117 | var response = await httpClient.GetAsync(fbUri);
118 | if (response.IsSuccessStatusCode)
119 | {
120 | var content = await response.Content.ReadAsStringAsync();
121 | var a = (JObject)JsonConvert.DeserializeObject(content);
122 |
123 | var login = a["name"];
124 | var image = "https://graph.facebook.com/me/picture?access_token=" + access_token;
125 | await Navigation.PushAsync(new ProfilePage(Services.Facebook, login.ToString(), image.ToString()));
126 | }
127 | }
128 |
129 | async Task ViewTwitterProfile(HttpClient httpClient)
130 | {
131 | var screen_name = _services.GetPropertyFromAccount(Services.Twitter, "screen_name");
132 | var oauth_consumer_key = _services.GetPropertyFromAccount(Services.Twitter, "oauth_consumer_key");
133 | var oauth_token_secret = _services.GetPropertyFromAccount(Services.Twitter, "oauth_token_secret");
134 | var oauth_timestamp = ToUnixTime(DateTime.UtcNow).ToString();
135 | var oauth_token = _services.GetPropertyFromAccount(Services.Twitter, "oauth_token");
136 | var oauth_nonce = Guid.NewGuid().ToString("N");
137 | var oauth_signature_method = "HMAC-SHA1";
138 | var oauth_version = "1.0";
139 |
140 | var twitterUri = "https://api.twitter.com/1.1/users/show.json?screen_name=" + screen_name;
141 |
142 | #region Create signature
143 | // Collecting parameters
144 | var parameters = new Dictionary()
145 | {
146 | {nameof(screen_name), screen_name },
147 | {nameof(oauth_consumer_key), oauth_consumer_key },
148 | {nameof(oauth_nonce), oauth_nonce },
149 | {nameof(oauth_signature_method), oauth_signature_method },
150 | {nameof(oauth_token), oauth_token },
151 | {nameof(oauth_timestamp), oauth_timestamp },
152 | {nameof(oauth_version), oauth_version },
153 |
154 | };
155 |
156 | var list = parameters.Keys.ToList();
157 | list.Sort();
158 |
159 |
160 | var queryString = String.Join("&", list.Select(key => String.Format("{0}={1}", Uri.EscapeDataString(key), Uri.EscapeDataString(parameters[key]))).ToArray());
161 |
162 | // Creating the signature base string
163 | var signatureBase = "GET&" + Uri.EscapeDataString("https://api.twitter.com/1.1/users/show.json") + "&" +
164 | Uri.EscapeDataString(queryString);
165 |
166 | var twitterKeys = new TwitterKeys();
167 | var signingkey = Uri.EscapeDataString(twitterKeys.ConsumerSecret) + "&" //;
168 | + Uri.EscapeDataString(oauth_token_secret);
169 |
170 | var oauth_signature = HashHmac(signatureBase, signingkey);
171 |
172 | #endregion
173 |
174 |
175 | var authValue = "oauth_consumer_key=\"" + oauth_consumer_key + "\", oauth_nonce=\"" + oauth_nonce + "\""
176 | + ", oauth_signature=\"" + Uri.EscapeDataString(oauth_signature) + "\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"" + oauth_timestamp +
177 | "\"," +
178 | " oauth_token=\"" + oauth_token + "\"," +
179 | " oauth_version=\"1.0\"";
180 | httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("OAuth", authValue);
181 |
182 |
183 | var twitterResponse = await httpClient.GetAsync(twitterUri);
184 | System.Diagnostics.Debug.WriteLine(twitterResponse);
185 | if (twitterResponse.IsSuccessStatusCode || twitterResponse.StatusCode == System.Net.HttpStatusCode.BadRequest)
186 | {
187 | var twitterContent = await twitterResponse.Content.ReadAsStringAsync();
188 | var a = (JObject)JsonConvert.DeserializeObject(twitterContent);
189 |
190 | var login = a["screen_name"];
191 | var image = a["profile_image_url"];
192 | await Navigation.PushAsync(new ProfilePage(Services.GitHub, login.ToString(), image.ToString()));
193 | }
194 | }
195 |
196 | public static long ToUnixTime(DateTime date)
197 | {
198 | return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
199 | }
200 |
201 | public static string HashHmac(string data, string key)
202 | {
203 | byte[] keyBytes = Encoding.UTF8.GetBytes(key);
204 | byte[] dataBytes = Encoding.UTF8.GetBytes(data);
205 | var algorithm = WinRTCrypto.MacAlgorithmProvider.OpenAlgorithm(MacAlgorithm.HmacSha1);
206 | CryptographicHash hasher = algorithm.CreateHash(keyBytes);
207 | hasher.Append(dataBytes);
208 | byte[] mac = hasher.GetValueAndReset();
209 |
210 | StringBuilder sBuilder = new StringBuilder();
211 | for (int i = 0; i < mac.Length; i++)
212 | {
213 | sBuilder.Append(mac[i].ToString("X2"));
214 | }
215 | return System.Convert.ToBase64String(mac);
216 | }
217 |
218 | protected override void OnAppearing()
219 | {
220 | var accounts = _services.Accounts;
221 |
222 | if (accounts.Contains(Services.GitHub))
223 | github.Text = "Ver perfil de GitHub";
224 | else
225 | github.Text = "Conectar GitHub";
226 |
227 | if (accounts.Contains(Services.Facebook))
228 | facebook.Text = "Ver perfil de Facebook";
229 | else
230 | facebook.Text = "Conectar Facebook";
231 |
232 | if (accounts.Contains(Services.Twitter))
233 | twitter.Text = "Ver perfil de Twitter";
234 | else
235 | twitter.Text = "Conectar Twitter";
236 |
237 | }
238 | }
239 | }
240 |
--------------------------------------------------------------------------------
/iOS/Authy.iOS.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | iPhoneSimulator
6 | {2BF68393-14DC-4139-8DA1-29CE597F3579}
7 | {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
8 | Exe
9 | Authy.iOS
10 | Authy.iOS
11 | Resources
12 |
13 |
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\iPhoneSimulator\Debug
20 | DEBUG;ENABLE_TEST_CLOUD;
21 | prompt
22 | 4
23 | iPhone Developer
24 | true
25 | true
26 | true
27 | true
28 | None
29 | i386
30 | HttpClientHandler
31 | Default
32 | x86
33 | Entitlements.plist
34 | 10.0
35 |
36 |
37 | pdbonly
38 | true
39 | bin\iPhone\Release
40 | prompt
41 | 4
42 | iPhone Developer
43 | true
44 | true
45 | true
46 | Entitlements.plist
47 | SdkOnly
48 | ARMv7, ARM64
49 | HttpClientHandler
50 | Default
51 | x86
52 |
53 |
54 | pdbonly
55 | true
56 | bin\iPhoneSimulator\Release
57 | prompt
58 | 4
59 | iPhone Developer
60 | true
61 | true
62 | None
63 | i386
64 | HttpClientHandler
65 | Default
66 | x86
67 |
68 |
69 | true
70 | full
71 | false
72 | bin\iPhone\Debug
73 | DEBUG;ENABLE_TEST_CLOUD;
74 | prompt
75 | 4
76 | iPhone Developer
77 | true
78 | true
79 | true
80 | true
81 | true
82 | true
83 | Entitlements.plist
84 | None
85 | ARMv7, ARM64
86 | HttpClientHandler
87 | Default
88 | x86
89 |
90 |
91 |
92 | ..\packages\modernhttpclient.2.4.2\lib\Xamarin.iOS10\ModernHttpClient.dll
93 | True
94 |
95 |
96 |
97 | ..\packages\Microsoft.Net.Http.2.2.29\lib\Xamarin.iOS10\System.Net.Http.Extensions.dll
98 | True
99 |
100 |
101 | ..\packages\Microsoft.Net.Http.2.2.29\lib\Xamarin.iOS10\System.Net.Http.Primitives.dll
102 | True
103 |
104 |
105 |
106 |
107 |
108 | ..\packages\Xamarin.Forms.2.3.2.127\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll
109 |
110 |
111 | ..\packages\Xamarin.Forms.2.3.2.127\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll
112 |
113 |
114 | ..\packages\Xamarin.Forms.2.3.2.127\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll
115 |
116 |
117 | ..\packages\Xamarin.Forms.2.3.2.127\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll
118 |
119 |
120 | ..\Components\xamarin.auth-1.2.3.1\lib\ios-unified\Xamarin.Auth.iOS.dll
121 |
122 |
123 | ..\packages\PCLCrypto.2.0.147\lib\xamarinios10\PCLCrypto.dll
124 |
125 |
126 | ..\packages\Validation.2.3.7\lib\dotnet\Validation.dll
127 |
128 |
129 | ..\packages\PInvoke.Windows.Core.0.3.152\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll
130 |
131 |
132 | ..\packages\PInvoke.Kernel32.0.3.152\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Kernel32.dll
133 |
134 |
135 | ..\packages\PInvoke.BCrypt.0.3.152\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.BCrypt.dll
136 |
137 |
138 | ..\packages\PInvoke.NCrypt.0.3.152\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.NCrypt.dll
139 |
140 |
141 |
142 |
143 | {61651E76-AA7A-4C37-AC6B-56D66B8BCFAE}
144 | Authy
145 |
146 |
147 |
148 |
149 | false
150 |
151 |
152 | false
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 | 1.2.3.1
174 | False
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
184 |
185 |
186 |
187 |
--------------------------------------------------------------------------------
/Droid/Authy.Droid.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | {2BA34DCF-7286-4C53-8A8B-B190E04A48C6}
7 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
8 | Library
9 | Authy.Droid
10 | Authy.Droid
11 | v6.0
12 | True
13 | Resources\Resource.designer.cs
14 | Resource
15 | Properties\AndroidManifest.xml
16 | Resources
17 | Assets
18 | false
19 |
20 |
21 | false
22 |
23 |
24 | true
25 | full
26 | false
27 | bin\Debug
28 | DEBUG;
29 | prompt
30 | 4
31 | None
32 | true
33 |
34 |
35 | true
36 | pdbonly
37 | true
38 | bin\Release
39 | prompt
40 | 4
41 | true
42 |
43 |
44 |
45 | ..\packages\modernhttpclient.2.4.2\lib\MonoAndroid\ModernHttpClient.dll
46 | True
47 |
48 |
49 | ..\packages\modernhttpclient.2.4.2\lib\MonoAndroid\OkHttp.dll
50 | True
51 |
52 |
53 |
54 |
55 | ..\packages\Microsoft.Net.Http.2.2.29\lib\monoandroid\System.Net.Http.Extensions.dll
56 | True
57 |
58 |
59 | ..\packages\Microsoft.Net.Http.2.2.29\lib\monoandroid\System.Net.Http.Primitives.dll
60 | True
61 |
62 |
63 |
64 |
65 |
66 | ..\packages\Xamarin.Android.Support.v4.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v4.dll
67 |
68 |
69 | ..\packages\Xamarin.Android.Support.Vector.Drawable.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.Vector.Drawable.dll
70 |
71 |
72 | ..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.Animated.Vector.Drawable.dll
73 |
74 |
75 | ..\packages\Xamarin.Android.Support.v7.AppCompat.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.AppCompat.dll
76 |
77 |
78 | ..\packages\Xamarin.Android.Support.v7.RecyclerView.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.RecyclerView.dll
79 |
80 |
81 | ..\packages\Xamarin.Android.Support.Design.23.3.0\lib\MonoAndroid43\Xamarin.Android.Support.Design.dll
82 |
83 |
84 | ..\packages\Xamarin.Android.Support.v7.CardView.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.CardView.dll
85 |
86 |
87 | ..\packages\Xamarin.Android.Support.v7.MediaRouter.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.MediaRouter.dll
88 |
89 |
90 | ..\packages\Xamarin.Forms.2.3.2.127\lib\MonoAndroid10\FormsViewGroup.dll
91 |
92 |
93 | ..\packages\Xamarin.Forms.2.3.2.127\lib\MonoAndroid10\Xamarin.Forms.Core.dll
94 |
95 |
96 | ..\packages\Xamarin.Forms.2.3.2.127\lib\MonoAndroid10\Xamarin.Forms.Platform.Android.dll
97 |
98 |
99 | ..\packages\Xamarin.Forms.2.3.2.127\lib\MonoAndroid10\Xamarin.Forms.Platform.dll
100 |
101 |
102 | ..\packages\Xamarin.Forms.2.3.2.127\lib\MonoAndroid10\Xamarin.Forms.Xaml.dll
103 |
104 |
105 | ..\packages\Xamarin.Auth.1.3.1.1\lib\MonoAndroid10\Xamarin.Auth.dll
106 |
107 |
108 |
109 | ..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll
110 |
111 |
112 | ..\packages\PInvoke.Kernel32.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Kernel32.dll
113 |
114 |
115 | ..\packages\PInvoke.BCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.BCrypt.dll
116 |
117 |
118 | ..\packages\PInvoke.NCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.NCrypt.dll
119 |
120 |
121 | ..\packages\Validation.2.2.8\lib\dotnet\Validation.dll
122 |
123 |
124 | ..\packages\PCLCrypto.2.0.147\lib\MonoAndroid23\PCLCrypto.dll
125 |
126 |
127 |
128 |
129 | {61651E76-AA7A-4C37-AC6B-56D66B8BCFAE}
130 | Authy
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
163 |
164 |
165 |
166 |
--------------------------------------------------------------------------------