Laravel persist $request->flash old() session - forms

So, I've build in functionality which redirects the logged in user to a pincode screen after 10 minutes of inactivity, when the user enters the correct pincode he or she is redirected to the page where he or she was navigating to.. So far so good but...
Imagine the user is filling out a form and waits ten minutes before hitting the submit button and is then redirected to the pincode page, after inputting the correct pincode he is on the form again but all data on it is gone.
What I want is to remember all the filled data, I've tried it via the old() method but that only persists for one request.
PincodeCheck Middleware
if($difference_in_minutes > config('pincode.lifetime')) {
return redirect()->route('pincode')->withInput();
}
PincodeController
public function index(Request $request)
{
// $request->old() is holding the values
return view('pincode.index');
}
public function unlock(Request $request)
{
// This is the after submit function, $request->old() is empty here
if(Hash::check($request->pincode, auth()->user()->pincode) == true) {
$request->session()->put('pincode-timestamp', date('U'));
$path = config('app.homeroute');
if($request->session()->has('intended.get.path')) {
$path = $request->session()->get('intended.get.path');
}
return redirect($path);
}
return redirect()->route('pincode');
}

Related

Form redirect for confirmation

Form redirect for confirmation can be currently managed using one of these two options:
1/ Flash message: using flashbag on the form page or another page like this:
$this->addFlash('success', 'Thank you');
return $this->redirectToRoute('confirmation_page');
2/ Confirmation page: using a dedicated confirmation like this:
return $this->redirectToRoute('confirmation_page');
BUT using option 2 makes the confirmation_page directly accessible from the browser without having submitted the form before. I am currently using flashbag mechanism to fix it by adding a $this->addFlash('success', true); before the redirection in the form and then checking the flashbag content in the confirmation page so that the route is accessible only once after being successfully redirected from the form.
Is there any best practice or more appropriate way to manage it?
/**
* #Route("/confirmation", methods="GET", name="confirmation_page")
*/
public function confirmation(): Response
{
$flashbag = $this->get('session')->getFlashBag();
$success = $flashbag->get("success");
if (!$success) {
return $this->redirectToRoute('app_home');
}
return $this->render('templates/confirmation.html.twig');
}
Flash Message is designed to display messages. Instead, use sessions in your application.
When submitting the confirmation form, create a variable in the session before the redirect
$this->requestStack->getSession()->set('verifyed',true);
return $this->redirectToRoute('confirmation_page');
Use the created variable in your method
public function confirmation(): Response
{
if (!$this->requestStack->getSession()->get('verifyed')) {
return $this->redirectToRoute('app_home');
}
return $this->render('templates/confirmation.html.twig');
}
Don't forget to inject the RequestStack into your controller
private RequestStack $requestStack;
public function __construct(RequestStack $requestStack)
{
$this->requestStack = $requestStack;
}

laravel 5.2 redirect after registration by id

I've found here some examples, but they are not answering how to redirect registered user to his own profile by id.
protected $redirectPath = '/profile/view/'.$user->id; Did not help.
I have a project where users are being authorized without email confirmation and they are sent to /home after registration.
Route to user profile is: /profile/view/id (id is unique of course).
I managed to send them there after login (in AuthController :
public function authenticated($request,$user)
{
return redirect('/profile/view/'.$user->id);
}
but redirect to profile after registration I can't handle.
Approach 1.
Let users view their own profile without ID.
route (make ID optional):
Route::get('profile/view/{id?}', ...);
controller:
public function view($id = null) {
if (is_null($id) { //set id of currently signed in user if id == null
$id = Auth::user()->id;
}
//continue as before
}
Approach 2.
Modify routes so redirect happens to correct url.
Note: order of routes is important
Route::get('profile/view', function() {
return redirect()->route('profile.view', ['id' => Auth::user()->id]);
});
Route::get('profile/view/{id}', ...)->name('profile.view');
Note: in both approaches auth middleware is a must, else you going to get error if user is not logged in (PHP error: Trying to get property of non-object on line X)
With both approaches you just redirect user to profile/view:
is shown profile (without ID in URL)
is redirected to proper url profile/view/ID.

Laravel Socialite with Facebook not logging in

I'm following the documentation exactly.
https://github.com/laravel/socialite and https://laravel.com/docs/5.1/authentication#social-authentication
I've created my app on Facebook and got everything working. When I click my log in with Facebook button, it authorizes the app and takes me back to my site.
However, it doesn't show me as logged in. If I dd() instead of the redirect below, I get all of the data from my Facebook account. But the pages that are only visible to logged in users, aren't visible.
Here is my controller:
public function redirectToProvider()
{
return Socialite::driver('facebook')->redirect();
}
public function handleProviderCallback()
{
$user = Socialite::driver('facebook')->user();
return redirect('my-profile')
->with('message', 'You have signed in with Facebook.');
}
Here are my routes:
Route::get('login/facebook', 'Auth\AuthController#redirectToProvider');
Route::get('login/facebook/callback', 'Auth\AuthController#handleProviderCallback');
Socialite is installed properly in composer.json. The classes are in config/app.php and the IDs for my FB app are in config/services.php.
Any ideas as to why it's not working?
In the handleProviderCallback method you need to create and authenticate the user returned by the driver.
Create the user if doesn't exist:
$userModel = User::firstOrNew(['email' => $user->getEmail()]);
if (!$userModel->id) {
$userModel->fill([.....]);
$userModel->save();
}
Then authenticate the user:
Auth::login($userModel);
Your method will look like this:
public function handleProviderCallback() {
$user = Socialite::driver('facebook')->user();
$userModel = User::firstOrNew(['email' => $user->getEmail()]);
if (!$userModel->id) {
$userModel->fill([.....]);//Fill the user model with your data
$userModel->save();
}
Auth::login($userModel);
return redirect('my-profile')
->with('message', 'You have signed in with Facebook.');
}

Symfony2 esi cache forms not working

I get to the weird situation. I have up to date server files with local files. This "flash message with error" appears when this is not valid:
if ($form->isValid() && $this->checkLastComment($commentRepository,$user,$status, $comment)) {
I have two urls. First /Home (working) for everyone where i load statuses with comments BUT I DO NOT CACHE THE PAGE
Then i have /Suggested url where i load statuses with comments BUT USING
$response->setPublic();
$response->setSharedMaxAge(3600);
I CACHE THE PAGE because its the same for all users.
But its weird because on local machine (caching is on i tested) everything runs normal when i want to create a comment... on prod, dev env.
On server it runs normal when i am under dev env.(caching is off) but when i try post comment on prod env. i get error flash message for the mentioned condition...
WTF? Where could be leak please? i have no idea.
The public esi cache somehow breaks my forms? or...?
One friend is able to post a comment there... another one is not.. weird... i wasn't before but after cache clear i am again able...
EDIT:
After lunch i tried it again and i am not able to post comment... wtf..
This is my header i see in chrome: (sending)
CommentForm[comment]:gllll
status_id:65084
CommentForm[_token]:4858119eccbc91da6219d4cbaa1b6c2e79dbd56a
comment_id:0
Using this jquery code:
var url=Routing.generate('create_comment', {"comment_id": comment_id_value, "status_id": status_id_value})+'.json';
$.post(url, $this.serialize(), function(data) {
To this controller:
public function createAction(Request $request, $comment_id=0, $status_id)
{
// first CHECK if user exists
$user=$this->getUser();
if ($user) {
$em=$this->getDoctrine()->getManager();
// GET REPOSITORIES
$statusRepository=$em->getRepository('WallBundle:Status');
$commentRepository=$em->getRepository('WallBundle:Comments');
$notifyRepository=$em->getRepository('NotifyBundle:Notify');
$userRepository=$em->getRepository('UserBundle:User');
// GET SM
$SM=$this->get('status_manager');
// GET status by ID
$status=$statusRepository->find($status_id);
// CHECK if this status exists
if ($status) {
$targetUser=$status->getUser();
if ($request->isMethod('POST') && ($this->getRequest()->getRequestFormat() == 'json')) {
if ($comment_id==0 || !$cE) {
$cE = new Comments();
}
$form = $this->createForm(new CommentFormType(), $cE);
$form->bind($request);
$comment=$form->getData()->getComment();
if ($form->isValid() && $this->checkLastComment($commentRepository,$user,$status, $comment)) {
AND the checkLastComment function
public function checkLastComment($commentRepository, User $user,Status $status, $comment)
{
// check if last comment was more than 10s ago
$lastCommentQueryArray=$commentRepository->getLastComment($user, $status);
$lastCommentTime=0;
$lastCommentContent='';
foreach ($lastCommentQueryArray as $lastComment) {
$lastCommentTime =$lastComment['time'];
$lastCommentContent=$lastComment['comment'];
}
if (($lastCommentTime+10>=time()) && (trim($lastCommentContent)==trim($comment))) {
return false;
}
else {
return true;
}
}
*But the bug should not be in the code because i am using this technique all over the web and everything runs good... only at this particularly page ITS NOT WORKING ... and the only difference between pages is that this one is cached ... + when i am creating a new comment it has nothing with cache isn't that right? it only takes the data from form which is on cached page... *

How do I avoid redirecting 404's to the login form in a Zend Framework 1 controller plugin?

I made a controller plugin to handle authentication. If a user tries to access a page without being logged in, it saves the route of the page he was trying to access, forwards to the login page, and then when the user logs in, it redirects him to where he was trying to go.
But if the user tries to access a nonexistent page while logged out, then it still forwards to the sign-in form, but when the user signs in, it brings up an error.
How do I bring up a 404 error before the user signs in? I think I need to detect whether the route is valid within dispatchLoopStartup(). How do I do that? Or is there some other way of doing this?
class Chronos_Controller_Plugin_Auth extends Zend_Controller_Plugin_Abstract
{
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$request->setParam('userName', $auth->getIdentity());
} else {
$request->setParam('origModule', $request->getModuleName())
->setParam('origController', $request->getControllerName())
->setParam('origAction', $request->getActionName())
->setModuleName('default')
->setControllerName('sign')
->setActionName('in');
}
}
}
Try something like this:
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
$dispatcher = Zend_Controller_Front::getInstance()->getDispatcher();
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$request->setParam('userName', $auth->getIdentity());
} else if ($dispatcher->isDispatchable($request)) {
$request->setParam('origModule', $request->getModuleName())
->setParam('origController', $request->getControllerName())
->setParam('origAction', $request->getActionName())
->setModuleName('default')
->setControllerName('sign')
->setActionName('in');
}
}