Is it possible to determine if the calling application is the current lock screen provider. What I mean by this is that in my app I would like to be able to query whether my app is the current lock screen provider or not. I have set up navigation to the default lock screen page using the following button click event, but I would like to disable the button if my app is already the current provider.
Edit*
I got this idea from the Twitter application, which allows you to make it the lock screen provider, and while it is the current lock screen provider, the button for this is disabled.
private async void LockScreenButton_Click(object sender, RoutedEventArgs e)
{
// Launch URI for the lock screen settings screen.
var op = await Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings-lock:"));
}
You can use the LockScreenManager to find out and prompt with the follow code:
if (LockScreenManager.IsProvidedByCurrentApplication == false)
{
LockScreenRequestResult request = await LockScreenManager.RequestAccessAsync();
// do something with result!
}
else
{
// we control the lockscreen!
}
Related
I implemented a toast with to open an url.
Here's the toast:
<toast>
<visual><binding template='ToastGeneric'><text>Go To bing.com</text></binding></visual></toast>
After that I added the handling to the OnStartAsync-Method:
public override Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
{
// navigates to Splash-Page
NavigationHelper.NavigationService = NavigationService;
NavigationService.Navigate(typeof(SplashPage));
// open the url
if (args is ToastNotificationActivatedEventArgs)
{
Windows.System.Launcher.LaunchUriAsync(new Uri("http://www.bing.com"));
}
return Task.FromResult<object>(null);
}
unfortunately the App crashes on the phone (it works like a charm on a desktop machine) every time I open the app with a tap on a notification with the following exeption (If I start the app without a tap on a notification, the normal way, it doesn't crash):
$exception {"Object reference not set to an instance of an object."} System.NullReferenceException
With the following stacktrace:
at Template10.Common.BootStrapper.<HandleResuming>d__99.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.ThrowAsync>b__6_0(Object state)
at System.Threading.WinRTSynchronizationContext.Invoker.InvokeCore()
at Windows.ApplicationModel.Core.UnhandledError.Propagate()
at Microsoft.HockeyApp.Extensibility.Windows.UnhandledExceptionTelemetryModule.CoreApplication_UnhandledErrorDetected(Object sender, UnhandledErrorDetectedEventArgs e)" string
I can't figure out the problem by myself and need some help right here.
If I remove the line with the Launch the app doesn't crash.
I want to protect our login actions by AntiforgeryToken attribute - I know why the exception from the topic occurs, however I can't seem to find any good solution for it.
Let say we have the following situations:
It's 8:00 AM, application users are coming to work, they sit down and starting the login process - right now it is very possible that some of the users will get the same ValidationToken. After the first one logs in - all other will see the above exception (or some other custom exception screen) when they attempt to login.
Some user logged in, then accidentally pressed the "back" button and attempted to log in again - while this is more unlikely, it can happen, and I don't want users to see exceptions when it does.
So the question is simple - how to prevent the above situations, or how to handle them so that users won't notice anything. I have tried the following:
Setting the AntiForgeryConfig.SuppressIdentityHeuristicChecks = true; in Application_Start in Global.asax - it didn't fix the problem, I still get the same exception
Setting the [OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")] on the method with [ValidateAntiForgeryToken] attribute - again, no luck there
Right now I was thinking to manually validate the token in action body, catch the error, and check if attempt was made by anonymous user:
public ActionResult SomeAction()
{
try
{
AntiForgery.Validate();
}
catch(HttpAntiForgeryException ex)
{
if(String.IsNullOrEmpty(HttpContext.User.Identity.Name))
{
throw;
}
}
//Rest of action body here
//..
//..
}
The above seems to prevent the errors - but is it safe? What alternatives are there?
Thanks in advance.
Best regards.
EDIT:
The final "solution" was to disable token validation on login form - there may be a better way to handle it, but it seems that all solutions I found, were ugly workarounds similar to mine proposed above.
Since there is no way to know how "safe" those alternatives are (if they are safe at all), we decided to do disable token validation on login.
Try setting (in global.cs):
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
This will add the name identifier to your token,
As for the double login issue try to use a script to document the date and time of the original submit to stop a second submit with the same token.
// jQuery plugin to prevent double submission of forms
jQuery.fn.preventDoubleSubmission = function() {
$(this).on('submit',function(e){
var $form = $(this);
if ($form.data('submitted') === true) {
// Previously submitted - don't submit again
e.preventDefault();
} else {
// Mark it so that the next submit can be ignored
$form.data('submitted', true);
}
});
// Keep chainability
return this;
};
So we know one thing; users like the back button and have a habit of the double click, this is a big issue with AntiforgeryToken.
But depending on what your application does there are ways to limit their compulsion to do so. The simplest of which is to do your best to try and make the visitor not feel like they need to “rewind” their request to alter it.
Ensure that form error messaging is clear and concise to ensure the
user knows what is wrong. Contexual errors give bonus points.
Always maintain form state between form submissions. Apart from
passwords or credit card numbers, there’s no excuse thanks the to MVC
form helpers. #Html.LabelFor(x => x.FirstName)
If forms are spread across tabs or hidden divs such as those used in
SPA frameworks like Angular or ember.js, be smart and show the
controller layouts or form that the errors actually originated from in
the form submission when displaying the error. Don’t just direct them
to the home controller or first tab.
“What’s going on?” - Keeping the user informed
When a AntiForgeryToken doesn’t validate your website will throw an Exception of type System.Web.Mvc.HttpAntiForgeryException.
If you’ve set up correctly you’ve got friendly errors turned on and this will mean your error page will not show an Exception and show a nice error page that tells them what is up.
You can make this a little easier by at least giving the user a more informative page targeted at these exceptions by catching the HttpAntiForgeryException.
private void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
if (ex is HttpAntiForgeryException)
{
Response.Clear();
Server.ClearError(); //make sure you log the exception first
Response.Redirect("/error/antiforgery", true);
}
}
and your /error/antiforgery view can tell them Sorry you have tried to submit the same information twice
Another Idea is to log the error and return the user to the login screen:
Create a HandleAntiforgeryTokenErrorAttribute class that Overrides the OnException method.
HandleAntiforgeryTokenErrorAttribute.cs:
public class HandleAntiforgeryTokenErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
filterContext.ExceptionHandled = true;
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(new { action = "Login", controller = "Account" }));
}
}
Global Filter:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new HandleAntiforgeryTokenErrorAttribute()
{ ExceptionType = typeof(HttpAntiForgeryException) }
);
}
}
I would also use a few tools to record all your information as login is critical part of your application
NLog for general logging and emails on critical application exceptions (including web exceptions).
Elmah for filtering and email of web exceptions.
EDIT:
Also you may want to look at a jQuery plugin called SafeForm. Link
EDIT:
I have seen allot of debate on this and everyone's views on the subject have valid points, How i look at it is (Taken from owasp.org)
Cross-Site Request Forgery (CSRF) is an attack that forces an end user
to execute unwanted actions on a web application in which they're
currently authenticated, CSRF attacks specifically target state-changing requests, not theft of data. The anti-forgery token is
specific to 'who is logged on'. So once you login, then go back, the
old token is no longer valid
Now i also use authorized IP addresses for login to allot of my applications with 2 factor authorization if the users IP address changes, so if Cross-Site Request Forgery was in play the user wouldn't match the IP address and request 2 factor authorization. almost like the way a security router would work. but if you want to keep it on your login page i don't see a problem as long as you have your friendly error pages set up people will not get upset as they will see they did something wrong.
I just wanted to add to the pool pro's answer - regarding the Filter part - that one must be careful since that will override all the exceptions about AntiforgeryToken, and if you (like myself) have this token validation on other parts of your application you might consider adding some validation to the filter:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new HandleAntiforgeryTokenErrorAttribute() { ExceptionType = typeof(HttpAntiForgeryException) });
}
}
public class HandleAntiforgeryTokenErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
string actionName = filterContext.Controller.ControllerContext.RouteData.Values["action"].ToString();
string controllerName = filterContext.Controller.ControllerContext.RouteData.Values["controller"].ToString();
if (actionName.ToLower() == "login" && controllerName.ToLower() == "account")
{
//Handle Error
//In here you handle the error, either by logging, adding notifications, etc...
//Handle Exception
filterContext.ExceptionHandled = true;
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(new { action = "Login", controller = "Account" }));
}
else
{
base.OnException(filterContext);
}
}
}
Note that I separate the cases where this exception is thrown on the Account/Login method, from all the other mehtods where a [ValidateAntiForgeryToken] might be used.
I have followed this tutorial on setting up Parse push notification in a Windows Phone app. This is my code:
public App() {
// Global handler for uncaught exceptions.
UnhandledException += Application_UnhandledException;
// Standard XAML initialization
InitializeComponent();
// Phone-specific initialization
InitializePhoneApplication();
// Language display initialization
InitializeLanguage();
// Show graphics profiling information while debugging.
if (Debugger.IsAttached) {
// Display the current frame rate counters.
Application.Current.Host.Settings.EnableFrameRateCounter = true;
// Show the areas of the app that are being redrawn in each frame.
//Application.Current.Host.Settings.EnableRedrawRegions = true;
// Enable non-production analysis visualization mode,
// which shows areas of a page that are handed off to GPU with a colored overlay.
//Application.Current.Host.Settings.EnableCacheVisualization = true;
// Prevent the screen from turning off while under the debugger by disabling
// the application's idle detection.
// Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run
// and consume battery power when the user is not using the phone.
PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
}
// Initialize the Parse client with your Application ID and .NET Key found on
// your Parse dashboard
ParseClient.Initialize("grpTmrClet8K35yeXg2HQKK8wl59VeC9ijH0I0dn", "os8EfSFq9maPBtDJ91Mq0xnWme8fLANhttTPAqKu");
// After calling ParseClient.Initialize():
this.Startup += async (sender, args) =>
{
// This optional line tracks statistics around app opens, including push effectiveness:
ParseAnalytics.TrackAppOpens(RootFrame);
// By convention, the empty string is considered a "Broadcast" channel
// Note that we had to add "async" to the definition to use the await keyword
await ParsePush.SubscribeAsync("testchannel");
};
}
// Code to execute when the application is launching (eg, from Start)
// This code will not execute when the application is reactivated
private async void Application_Launching(object sender, LaunchingEventArgs e) {
await ParseAnalytics.TrackAppOpenedAsync();
}
When I send a push notification from the Parse dashboard it doesn't get received. I have tried running both on the emulator (Windows Phone 8.0) and device (8.1), with app in foreground, background and closed with the same negative result.
When I use a channel like "testchannel" above and use the segment options, the channel name appears in the dropdown list of options indicating that the app is at least connecting Parse, but it just wont receive the notifications.
Hope someone can help me identify what I am missing. Thanks in advance.
If you are developing a Windows Phone 8.1 app, make sure you've enabled toast notification in the manifest file.
I don't quite understand everything about Parse just yet, but this is what works for me.
In App.xaml.cs:
public App()
{
this.InitializeComponent();
this.Suspending += this.OnSuspending;
ParseClient.Initialize("wSjuNTbtjVLRaedXvOoaf9S5cTbkuQohTulNZ2vS", "nWZMhXRet9Wotlgikb9aUdKf5GFtRiMvduw7w68z");
}
We subscribe and enable analytics OnLaunched:
protected async override void OnLaunched(LaunchActivatedEventArgs e)
//Generated codes go here
await ParsePush.SubscribeAsync("testchannel");
await ParseAnalytics.TrackAppOpenedAsync();
That would simply do the trick. You should modify the code according to your needs. Hope this helps.
I have created two Chrome apps and I want to pass some data (string format) from one Chrome app to another Chrome app. Appreciate if someone can help me with showing the correct way of doing this?
It's an RTFM question.
From Messaging documentation (note that it mentions extensions, but it works for apps):
In addition to sending messages between different components in your extension, you can use the messaging API to communicate with other extensions. This lets you expose a public API that other extensions can take advantage of.
You need to send messages using chrome.runtime.sendMessage (using app ID) and receive them using chrome.runtime.onMessageExternal event. If required, long-lived connections can also be established.
// App 1
var app2id = "abcdefghijklmnoabcdefhijklmnoab2";
chrome.runtime.onMessageExternal.addListener(
// This should fire even if the app is not running, as long as it is
// included in the event page (background script)
function(request, sender, sendResponse) {
if(sender.id == app2id && request.data) {
// Use data passed
// Pass an answer with sendResponse() if needed
}
}
);
// App 2
var app1id = "abcdefghijklmnoabcdefhijklmnoab1";
chrome.runtime.sendMessage(app1id, {data: /* some data */},
function(response) {
if(response) {
// Installed and responded
} else {
// Could not connect; not installed
// Maybe inspect chrome.runtime.lastError
}
}
);
I have followed all the steps given in the documentation to register for a push notification from the Parse website. (All the steps in the sense I downloaded the default project and added event handler to handle the incoming toast notification).
ParseClient.Initialize("x0uNa3Q164SVGKbH4mxZJaxWxsuYtslB5tVPj893",
"cXFv9RQAoray9xFdwdcZCHXrrkrM6KNd0WyN194H");
this.Startup += async (sender, args) =>
{
// This optional line tracks statistics around app opens, including push effectiveness:
ParseAnalytics.TrackAppOpens(RootFrame);
// By convention, the empty string is considered a "Broadcast" channel
// Note that we had to add "async" to the definition to use the await keyword
await ParsePush.SubscribeAsync("");
};
ParsePush.ToastNotificationReceived += ParsePushOnToastNotificationReceived;
and the handler
private void ParsePushOnToastNotificationReceived(object sender,
NotificationEventArgs notificationEventArgs)
{
var s = new ShellToast();
s.Content = notificationEventArgs.Collection.Values.First();
s.Title = "My Toast";
s.Show();
}
private async void Application_Launching(object sender, LaunchingEventArgs e)
{
await ParseAnalytics.TrackAppOpenedAsync();
}
When I run the app in the emulator it registers the app and I can verify it in my dashboard. But as soon as I send push notification from the website number of registered devices will be shown as 0 and the app doesnt receive the notification.
One thing to mention is this behavior is not consistent. Sometimes the app does receive the notification. Can anyone mention the reason for this or any other point I am missing?
One thing to note is that ShellToast.Show() should only be used from background task. If you call it when an app is in the foreground, toast won't be shown. http://msdn.microsoft.com/en-US/library/windowsphone/develop/microsoft.phone.shell.shelltoast.show(v=vs.105).aspx
So, be sure your app is not in the foreground when you expect to see toast notification.
Firstly you will be shown toast notification only if the foreground app is not running. If your app is running when you receive push notification you have to do like:
void ParsePushOnToastNotificationReceived(object sender,
NotificationEventArgs notificationEventArgs)
{
Deployment.Current.Dispatcher.BeginInvoke(()=>{
// do anything
MessageBox.Show("got notification");
});
}
If your app is not running the os will handle the notification properly, you dont have to do anything.