Asked  7 Months ago    Answers:  5   Viewed   40 times

In laravel for registration I'm using encrypt algorithm for password instead of inbuilt bcrypt function in Laravel because to get password and send it to mail when password is forgot.

But decrypt it is showing a error like

DecryptException The MAC is invalid in Encrypter.php (line 184)

This , when I run this code it is working on local but server itself it is not working below i have mentioned the code , can anyone please help

public function forgotpassword(Request $request)
{
  $email=$request->email;
  $selectemail = User::select('email','password','name')
     ->where('email',$email)
     ->first();     

  if($selectemail)                       
  {                                 
    $password=decrypt($selectemail->password);
    $data = array( 'email' => $selectemail->email,'password' => $password , 'name' => $selectemail->name);

    Mail::send('email.resetpassword',$data,function($message) use ($email)
    {
      $message->to([$email])->subject('Forgot Password Letgo');
    });
      echo "Mail has sent successfully";
  } else {
    echo "This email is not yet registered";
  }             
}   

 Answers

82

The problem is you generated a new APP_KEY, then if you try to decrypt the old encrypted data it will show the DecryptException: The MAC is invalid.

If you want to decrypt the old data you need to restore your old APP_KEY.

After realizing that, now, adding a new problem there, if you stored new data with another APP_KEY or another encryption method you have a problem on the data because they are mixed on the table.

In case you don't know when do you started with the new encrypt method or differentiate the new encrypted entries, the fastest solution would be reset all the passwords with the new encrypt method.

You can learn more about how Laravel encryption works on the official Laravel docs.

Wednesday, March 31, 2021
 
Litty
answered 7 Months ago
72

Actually i'm not even mad that's amazing because I found a solution to my problem... just around 5 min after I post my question... And I spend around 2 hours to find a solution...

All I did was:

php artisan clear-compiled
php artisan ide-helper:generate
php artisan optimize

and reload the blade.php.

I have no idea why, but it works now. It seems I forgot to run the above commands after I got Laravel Collective 5.2 in the project. This could be the reason that form command didn't work. .___.;;

I hope someone could use this information for their own project.

Wednesday, March 31, 2021
 
EurekA
answered 7 Months ago
40

As far as I can see and understand you're telling your unit test that when you call $request->has() on your request object that it should return the $requestParams array, not true or false, or anything else.

Unless you specifically check what is send with a method call your mock doesn't actually care what is send, it just cares that it was called.

You might want to explore creating an empty request and filling it with data if that is possible in your use case as that'll let you run your unit test with more ease and less issues. This won't work in all cases.

You could include what assertions you're making in your unit test so we can see more clearly what you're running into, but as it is. It returns exactly what you're telling it to return. Even if that's not what you actually want it to return.

Mocks are used to separate your Unit-Test from the rest of your system. As such you usually tend to only check if a specific method is called to see if your code actually exits to the class you mocked and if it has the expected data you'd send along. In some extreme cases you can want to mock the system you're actually testing, but this usually indicates that your code is too dependent on other classes or it's doing too much.

Another reason to use mocks is to satisfy Type Casting constraints in your method calls. In these cases you'll usually create an empty mocked object and fill it with some dummy data your code will accept or break on to test the code.

In your case it seems you want to check if your code actually works correctly and for this I'd suggest either not mocking the request, or making specific tests where you tell it to return true, or false (test for both cases)

So something along the lines of:

$request->expects($this->any())
    ->method('has')
    ->with('username')
    ->willReturn(true); // or false in your next test

Edit: As you mentioned in the comment Below you ran into the issue that you're using the has method multiple times in your code and ran into issues.

The Questions I've linked to in my response comment go into greater detail but to sum it up, you can use an inline function or the at() method to deal with multiple cases.

With at() you can supply specific iterations of the code to hit only that bit of the test. It has been mentioned that this makes your tests rather brittle as any has added before the previous ones would break the test.

$request->expects($this->at(0))
    ->method('has')
    ->with('username')
    ->willReturn('returnValue');

$request->expects($this->at(1))
    ->method('has')
    ->with('email')
    ->willReturn('otherReturnValue');

The inline function (callback) solution would allow you to customize your test to allow multiple cases and to return data as required. Unfortunately I'm not too familiar with this concept as I haven't used it myself before. I suggest reading the PHPUnit docs for more information about this.

In the end I'd still suggest not mocking the request and instead making an empty request that you'll fill with the data you want to check. Laravel comes with some impressive methods that'll let you manually fill the request with a lot of data you'd usually test against.

For example you can add data (post/get data) by using

request->add(['fieldname' => 'value'])

As a last few pointers I'd like to mention that it seems you use var_dump. Laravel comes with two of it's own functions that are similar and quite useful in debugging. You can use dd(); or dump(); dd(); dumps and stops the execution of code, while dump(); just outputs whatever you decide. so you could do dd($request); or dump($request); and see what the variables/class objects/etc holds. It'll even put it in a rather spiffy layout with some Javascript and such to allow you to see what's in it and such. Might want to check it out if you didn't knew it existed.

Wednesday, March 31, 2021
 
Daveel
answered 7 Months ago
78

Solution # 1

The inflate method accepts optional 'ViewGroup root' argument:

public View inflate (int resource, ViewGroup root, boolean attachToRoot)

If we have value to pass as 'root' parameter, than hence we can use it to get 'activity context' from where we can get correct LayoutInflater:

ViewGroup root > activity context > LayoutInflater

So my code could be:

private void add(LinearLayout container) {
    LayoutInflater inflater = getInflater(container.getContext());
    inflater.inflate(R.layout.my_template, container, true);
}

Solution # 2

Just tried to set Application Context theme programmatically, and it works:

getApplicationContext().setTheme(R.style.MyTheme);

I think it was logical to expect this markup:

<application 
    android:icon="@drawable/icon" 
    android:label="@string/app_name"
    android:theme="@style/MyTheme"
    >

to set it automatically, but it does not.

Thursday, June 10, 2021
 
CAMason
answered 5 Months ago
80

(The standard disclaimer about not abusing the C preprocessor without a really good reason applies here.)

It's certainly possible to do what you want to do. You need a STRINGIFY macro and a bit of macro indirection.

Typically, STRINGIFY is defined with one level of indirection, to allow the C preprocessor to expand its arguments before they undergo stringification. One implementation is:

/* The # operator converts symbol 'v' into a string */
#define STRINGIFY0(v) #v
#define STRINGIFY(v) STRINGIFY0(v)

However, you'll find that this isn't enough:

#define _ACD 5, 5, 5, 30
#define DEFAULT_NETWORK_TOKEN_KEY_CLASS   _ACD 
#define DEFAULT_NETWORK_TOKEN_KEY { DEFAULT_NETWORK_TOKEN_KEY_CLASS }

#define START_MSG STRINGIFY(DEFAULT_NETWORK_TOKEN_KEY_CLASS)
const char startMsg[] = START_MSG;

Here, STRINGIFY(DEFAULT_NETWORK_TOKEN_KEY_CLASS) expands to STRINGIFY0(5,5,5,30), and the C preprocessor complains that you've given STRINGIFY0 too many arguments.

The solution is to delay the expansion of _ACD so it only expands to 5,5,5,30 when you want it to. To do this, define it as a function-like macro:

#define _ACD() 5, 5, 5, 30

This way, _ACD will only be expanded when you "call" it: _ACD(). DEFAULT_NETWORK_TOKEN_KEY_CLASS will now expand to _ACD, and you have to expand it further by "calling" it: DEFAULT_NETWORK_TOKEN_KEY_CLASS().

The following code illustrates the solution:

#include <stdio.h>

#define STRINGIFY0(v) #v
#define STRINGIFY(v) STRINGIFY0(v)

#define _ACD() 5, 5, 5, 30
#define DEFAULT_NETWORK_TOKEN_KEY_CLASS   _ACD 
#define DEFAULT_NETWORK_TOKEN_KEY { DEFAULT_NETWORK_TOKEN_KEY_CLASS() }

#define START_MSG STRINGIFY(DEFAULT_NETWORK_TOKEN_KEY_CLASS)

const char startMsg[] = START_MSG;

int main(int argc, char** argv)
{
  printf("%sn",startMsg);
  return 0;
}
Saturday, July 3, 2021
 
redrom
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share