How can I properly redirect to a route in Laravel 8? - laravel-8

I tried every similar question I found here, but none worked.
I have these two groups and I just want to redirect to each specific route according to the type of user, i`m using Laravel 8 + inertia and vue 3
Route::prefix('user')->namespace('App\Http\Controllers\Customer')->middleware(['role', 'auth'])->group(function () {
Route::resource('dashboard', DashboardController::class)->only('index');
Route::resource('accounts', MyAccountController::class);
});
Route::prefix('staff')->namespace('App\Http\Controllers\Staff')->middleware(['role', 'auth'])->group(function () {
Route::resource('dashboard', DashboardController::class)->only('index');
Route::resource('accounts', MyAccountController::class);
});
// role middleware
public function handle(Request $request, Closure $next)
{
if (!\Auth::check())
return redirect('login.index');
if ($request->user() && $request->user()->isAdmin()) {
$path = $request->path();
if( strpos($request->path(), 'user/') !== FALSE ) {
$path = str_replace('staff/', 'user/', $request->path());
}
return redirect($path);
} else {
$path = $request->path();
if( strpos($request->path(), 'staff/') !== FALSE ) {
$path = str_replace('staff/', 'user/', $request->path());
}
return redirect($path);
}
return $next($request);
}

Related

Regenerate missing package-lock.json file from node_modules

The original developers for my project didn't commit the package-lock.json file, only the package.json file. I created my own package-lock.json file when I did npm install, but that was 5 years ago and I didn't realise at the time that I needed to check the file into Git because I stupidly assumed that the original developers knew what they were doing.
Now we have a second developer, plus I need to add a new package. Both of these things require that I have the "original" package-lock.json file.
Is there a way to reconstruct the package-lock.json file using npm from the contents of my node_modules directory which is now the only source of truth? I have looked at various answers and tried a few npm commands, such as npm i --package-lock-only, but that gave me a file as it would be created today, not the file based on my node_modules directory.
So, not finding an answer, I've spent the last two days writing some PHP code to do the job for me. The code is not complete, for example it assumes that the only production modules will be angular and angular-ui-router because I didn't need anything more complicated with my project. However, it's good enough to create an exact copy of the package-lock.json file, minus optional dependencies that weren't installed, because it can't resolve versions of packages it can't find.
The code was written to work, not necessarily to be easy to understand, so it might be a little opaque.
It's run with:
<?php
$package_lock = new PackageLock();
// or
$package_lock = new PackageLock('path/to/packages');
The code:
<?php
class PackageLock {
protected const MY_PACKAGE = 'my-package';
protected const MY_VERSION = '0.0.0';
//
protected const FILE_NAME = 'package-lock-recreated.json';
protected const NODE_MODULES = 'node_modules';
//
protected array $modules = [];
protected array $packages = [
'name' => PackageLock::MY_PACKAGE,
'version' => PackageLock::MY_VERSION,
'lockfileVersion' => 1,
'requires' => true,
];
protected string $dir;
public function __construct(string $dir = '.') {
$this->dir = $dir;
$this->packages['dependencies'] = $this->parse();
file_put_contents(PackageLock::FILE_NAME, preg_replace('/^( +)\1/m', '$1', json_encode($this->packages, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)));
}
protected function parse(array $priors = []): array {
$nm = PackageLock::NODE_MODULES;
$requests = $priors;
array_unshift($requests, '');
$current_priors = $requests;
$current_priors[] = '';
$main_path = $this->dir . implode("/{$nm}/", $current_priors);
$dir_pattern = $main_path . '*';
$dirs = glob($dir_pattern);
$current_dir = dirname($dir_pattern, 2);
$dependencies = [];
foreach ($dirs as $dir) {
$module_name = basename($dir);
if (in_array($module_name, ['angular-moment-picker', 'json-loader', 'moment-timezone'])) {
continue;
}
$this->modules[$dir] = json_decode(file_get_contents("{$dir}/package.json"));
}
foreach ($this->modules as $dir => $module) {
if (strpos($dir, $main_path) !== 0) {
continue;
}
$module_name = basename($dir);
$dependencies[$module_name] = [
'version' => $module->version,
'resolved' => $module->_resolved,
'integrity' => $module->_integrity,
];
if (!$this->is_prod($module_name)) {
$dependencies[$module_name]['dev'] = true;
}
if ($this->is_optional($main_path . $module_name)) {
$dependencies[$module_name]['optional'] = true;
}
if (!empty($module->dependencies) && (array)$module->dependencies) {
$dependencies[$module_name]['requires'] = $module->dependencies;
}
if (is_dir("{$current_dir}/{$nm}/{$module_name}/{$nm}")) {
$dependencies[$module_name]['dependencies'] = $this->parse_dependencies($priors, $module_name);
}
}
return $dependencies;
}
protected function is_prod($module_name): bool {
return in_array($module_name, ['angular', 'angular-ui-router']);
}
protected function parse_dependencies(array $priors, string $module_name): array {
$priors[] = $module_name;
return $this->parse($priors);
}
protected function is_optional($key): bool {
$module_name = basename($key);
$is_optional = false;
if (!array_key_exists($key, $this->modules)) {
var_dump("Key does not exist: {$key}");
}
if ($this->modules[$key]) {
foreach ($this->modules[$key]->_requiredBy as $parent_module_path) {
if (in_array($parent_module_path, ['/', '#USER', '#DEV:/'])) {
break;
}
$parent_module_path = $this->module_to_file_path($parent_module_path);
if (array_key_exists($parent_module_path, $this->modules)) {
$is_optional = $this->check_optional($parent_module_path, $module_name);
}
else {
$file_name = "{$parent_module_path}/package.json";
if (!file_exists($file_name)) {
$is_optional = true;
}
else {
$this->modules[$parent_module_path] = json_decode(file_get_contents($file_name));
$is_optional = $this->check_optional($parent_module_path, $module_name);
unset($this->modules[$parent_module_path]);
}
}
if (!$is_optional) {
break;
}
}
}
return $is_optional;
}
protected function module_to_file_path($module_path): string {
return $this->dir . str_replace('/', '/' . PackageLock::NODE_MODULES . '/', $module_path);
}
protected function check_optional(string $parent_module_path, $module_name): bool {
if (
!empty($this->modules[$parent_module_path]->optionalDependencies)
&& property_exists($this->modules[$parent_module_path]->optionalDependencies, $module_name)
) {
$is_optional = true;
}
else {
$is_optional = $this->is_optional($parent_module_path);
}
return $is_optional;
}
}

After successful login user is not logged into YII2 frontend

If I run the login function it prints User.
public function actionLogin(){
if ($model->load(Yii::$app->request->post()) && $model->login()) {
if (Yii::$app->user->isGuest) {
echo "guest";
} else {
echo "User";
}
return $this->redirect(['dashboard']);
}
After redirect If I run the dashboard function it prints guest.
public function actionDashboard()
{
if (Yii::$app->user->isGuest) {
echo "guest";
} else {
echo "User";
}
}
My Login model:
public function login()
{
if ($this->validate()) {
return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0);
} else {
return false;
}
}
This is getUser function:
protected function getUser()
{
if ($this->_user === null) {
$this->_user = Customer::findByEmail($this->email);
}
return $this->_user;
}
Please help me to check in another function whether or not the user is logged in?
I successfully fixed this problem.
just change the backend/config/main.php or frontend/config/main.php
change this
'components' => [
'user' => [
'identityClass' => 'common\models\Customer', //or Any models you want
'enableAutoLogin' => true,
],
]

Silex - How to pass Request $request to $app->error(function (\Exception $e, $code) use ($app) {

I am new to Silex. I am trying to pass Request $request to $app->error(...){...}. Normally it would look like so:
$app->error(function(\Exception $e, $code) use ($app) { ...
I want to use Request within the error controller. The code below will generate en error. Any idea how to snick the Request $request object into this controller ? so I will have access to request->getPathInfo() ?
//...
$app->error(function(\Exception $e, $code, Request $request) use ($app) {
if (404 === $code) {
$path = $request->getPathInfo();
$path = explode('/',$path);
if($path[1] == 'php'){
return $app->redirect($app['url_generator']->generate('php'));
}
if($path[1] == 'css'){
return $app->redirect($app['url_generator']->generate('css'));
}
//...
return $app->redirect($app['url_generator']->generate('home'));
}
// Do something else (handle error 500 etc.)
});
// RUN
$app->run();
$path = $app['request']->getPathInfo();
$app->error(function(\Exception $e, $code) use ($app) {
if (404 === $code) {
$path = $app['request']->getPathInfo();
$path = explode('/',$path);
echo $path[1];
if($path[1] == 'php'){
return $app->redirect($app['url_generator']->generate('php'));
}
if($path[1] == 'css'){
return $app->redirect($app['url_generator']->generate('css'));
}
//...
return $app->redirect($app['url_generator']->generate('home'));
}
// Do something else (handle error 500 etc.)
});
// RUN
$app->run();
Now I can redirect users when 404 based on the area they are in - to different predefined paths.
$this->error(
function (\Exception $e, Request $request, $code) {
//yours code here
}
);
Try this code,
Request::createFromGlobals()

Mithril redraw only 1 module

If I have like 10 m.module on my page, can I call m.startComputation, m.endComputation, m.redraw or m.request for only one of those modules?
It looks like any of these will redraw all of my modules.
I know only module 1 will be affected by some piece of code, I only want mithril to redraw that.
Right now, there's no simple support for multi-tenancy (i.e. running multiple modules independently of each other).
The workaround would involve using subtree directives to prevent redraws on other modules, e.g.
//helpers
var target
function tenant(id, module) {
return {
controller: module.controller,
view: function(ctrl) {
return target == id ? module.view(ctrl) : {subtree: "retain"}
}
}
}
function local(id, callback) {
return function(e) {
target = id
callback.call(this, e)
}
}
//a module
var MyModule = {
controller: function() {
this.doStuff = function() {alert(1)}
},
view: function() {
return m("button[type=button]", {
onclick: local("MyModule", ctrl.doStuff)
}, "redraw only MyModule")
}
}
//init
m.module(element, tenant("MyModule", MyModule))
You could probably also use something like this or this to automate decorating of event handlers w/ local
Need multi-tenancy support for components ? Here is my gist link
var z = (function (){
//helpers
var cache = {};
var target;
var type = {}.toString;
var tenant=function(componentName, component) {
return {
controller: component.controller,
view: function(ctrl) {
var args=[];
if (arguments.length > 1) args = args.concat([].slice.call(arguments, 1))
if((type.call(target) === '[object Array]' && target.indexOf(componentName) > -1) || target === componentName || target === "all")
return component.view.apply(component, args.length ? [ctrl].concat(args) : [ctrl])
else
return {subtree: "retain"}
}
}
}
return {
withTarget:function(components, callback) {
return function(e) {
target = components;
callback.call(this, e)
}
},
component:function(componentName,component){
//target = componentName;
var args=[];
if (arguments.length > 2) args = args.concat([].slice.call(arguments, 2))
return m.component.apply(undefined,[tenant(componentName,component)].concat(args));
},
setTarget:function(targets){
target = targets;
},
bindOnce:function(componentName,viewName,view) {
if(cache[componentName] === undefined) {
cache[componentName] = {};
}
if (cache[componentName][viewName] === undefined) {
cache[componentName][viewName] = true
return view()
}
else return {subtree: "retain"}
},
removeCache:function(componentName){
delete cache[componentName]
}
}
})();

Yii::app()->user->isGuest always returns true even though login was successful

I started to make some differences between those users which have authenticated and those that not. For this, i am using
Yii::app()->user->id;
However, in a determined view i put the following code:
<?php
if(Yii::app()->user->isGuest) {
print("Welcome back Guest!");
print("Your id is ".Yii::app()->user->id);
} else {
print("Welcome back ".Yii::app()->user->name);
print("Your id is ".Yii::app()->user->id);
}?>
And i always get the "welcome back guest!", whether i have logged in (successfully) or not. And if i have logged in, then it displays the welcome message together with the user's id!
EDIT
#briiC.lv
Hey.. sorry for the late reply, I hope you are still following this! I am not extending the given UserIdentity class. Is this mandatory? Since i still dont get very well the whole authorization issue, i thought it would be best to give a try with the class they provide, and then extend with my own functionality.. Anyway, next i post my UserIdentity class with its small tweaks.. maybe the problem lies here??
<?php class UserIdentity extends CUserIdentity{
private $_id;
public function authenticate()
{
$user = Users::model()->findAll('username=\''.$this->username.'\' AND password=\''.$this->encryptedPassword.'\'');
if(!isset($user[0]))
{
return false;
}
else
{
$this->setState('id', $user[0]->id);
$this->username = $user[0]->username;
$this->errorCode=self::ERROR_NONE;
return true;
}
}
public function getId()
{
return $this->_id;
}
}
Here is the output i got when i started to log as you suggested; i got this output immediately after successfully logging in.
[05:23:21.833][trace][vardump] CWebUser#1 (
[allowAutoLogin] => true
[guestName] => 'Guest'
[loginUrl] => array ( '0' => '/site/login' )
[identityCookie] => null
[authTimeout] => null
[autoRenewCookie] => false
[autoUpdateFlash] => true
[CWebUser:_keyPrefix] => '0f4431ceed8f17883650835e575b504b'
[CWebUser:_access] => array()
[behaviors] => array()
[CApplicationComponent:_initialized] => true
[CComponent:_e] => null
[CComponent:_m] => null
)
Any help is much appreciated!
Maybe you can try to debug harder:
change messages to something like this:
if(Yii::app()->user->isGuest) {
print("Not logged");
} else {
print_r(Yii::app()->user);
print("Welcome ".Yii::app()->user->name);
print("Your id is ".Yii::app()->user->id);
}
And check session variable in your config/main.php file
...
'session' => array(
'autoStart'=>true,
),
...
The error is in the following line
$this->setState('id', $user[0]->id);
As seen in the official yii documentation regarding auth & auth, setState should be used for anything but the id field. In order to implement the key Yii will use to identify your user, return a unique value per user in the Identity getId() function.
In your case, this means you simply have to change the above line into the following:
$this->_id = $user[0]->id;
Regarding the actual inner working of the login procedure, I'd recommend a look at the CWebUser class, and especially at its login function, which is responsible for the actual storage of the Identity getId() return value.
when you call authenticate function login user as
$userIdentity = new UserIdentity($username, $password);
$userIdentity->authenticate();
if ($userIdentity->errorCode===UserIdentity::ERROR_NONE) {
Yii::app()->user->login($userIdentity,0);
}
and fetch id as
echo 'id='.Yii::app()->user->getId();
apply this code and check
I have faced same problem and found that only one line in UserIdentity Component will resolve this issue.
This is your code:
else
{
$this->setState('id', $user[0]->id);
$this->username = $user[0]->username;
$this->errorCode=self::ERROR_NONE;
return true;
}
Update this code by this one
else
{
$this->_id = $user[0]->id;
$this->setState('id', $user[0]->id);
$this->username = $user[0]->username;
$this->errorCode=self::ERROR_NONE;
return true;
}
First of all, you need to know condition that sets guest and logged-in user apart.
Based on Yii master's branch CWebUser::getIsGuest():
public function getIsGuest()
{
return $this->getState('__id')===null;
}
Compared to your code:
$user = Users::model()->findAll('username=\''.$this->username.'\' AND password=\''.$this->encryptedPassword.'\'');
if(!isset($user[0])) {
// false
} else {
$this->setState('id', $user[0]->id); // this is for persistent state sakes
...
}
}
In short: you did supply 'id' to Identity persistent state but Yii CWebUser expecting '__id' based on UserIdentity::getId().
Solution is pretty dead simple. You just need to set $this->_id
$user = Users::model()->findAll('username=\''.$this->username.'\' AND password=\''.$this->encryptedPassword.'\'');
if(!isset($user[0])) {
// false
} else {
$this->setState('id', $user[0]->id); // this is for persistent state sakes
$this->_id = $user[0]->id; // this is UserIdentity's ID that'll be fetch by CWebUser
...
}
}
This routine explains how CWebUser get UserIdentity's ID: https://github.com/yiisoft/yii/blob/master/framework/web/auth/CWebUser.php#L221
Please do test it out.
Please try following code. Its working well
//config/main.php
return array (
'component' => array(
'session' => array(
'savePath' => INSTANCE_ROOT.DS.'runtime'.DS.'session',
'autoStart' => true,
),
)
);
// LoginController
class LoginController extends CController {
public function actionLogin () {
if(isset($_POST['LoginForm']))
{
$form = new LoginForm;
$form->setAttributes($_POST['LoginForm']);
if ($form->validate()) {
$user = Users::model()->find('upper(username) = :username', array(
':username' => strtoupper($form->username)));
if($user)
return $this->authenticate($user, $form);
else {
Yii::log( 'som.....', 'error');
$form->addError('password', Yii::t('Username or Password is incorrect'));
}
return false;
}
}
}
protected function authenticate($user, $form) {
$identity = new UserIdentity($user->username, $form->password);
$identity->authenticate();
switch($identity->errorCode) {
case UserIdentity::ERROR_NONE:
$duration = $form->rememberMe ? 3600*24*30 : 0; // 30 days
Yii::app()->user->login($identity,$duration);
return $user;
break;
case UserIdentity::ERROR_EMAIL_INVALID:
$form->addError("password",Yii::t('Username or Password is incorrect'));
break;
case UserIdentity::ERROR_STATUS_INACTIVE:
$form->addError("status",Yii::t('This account is not activated.'));
break;
case UserIdentity::ERROR_STATUS_BANNED:
$form->addError("status",Yii::t('This account is blocked.'));
break;
case UserIdentity::ERROR_STATUS_REMOVED:
$form->addError('status', Yii::t('Your account has been deleted.'));
break;
case UserIdentity::ERROR_PASSWORD_INVALID:
Yii::log( Yii::t(
'Password invalid for user {username} (Ip-Address: {ip})', array(
'{ip}' => Yii::app()->request->getUserHostAddress(),
'{username}' => $form->username)), 'error');
if(!$form->hasErrors())
$form->addError("password",Yii::t('Username or Password is incorrect'));
break;
return false;
}
}
}
class UserIdentity extends CUserIdentity {
const ERROR_EMAIL_INVALID=3;
const ERROR_STATUS_INACTIVE=4;
const ERROR_STATUS_BANNED=5;
const ERROR_STATUS_REMOVED=6;
const ERROR_STATUS_USER_DOES_NOT_EXIST=7;
public function authenticate()
{
$user = Users::model()->find('username = :username', array(
':username' => $this->username));
if(!$user)
return self::ERROR_STATUS_USER_DOES_NOT_EXIST;
if(Users::encrypt($this->password)!==$user->password)
$this->errorCode=self::ERROR_PASSWORD_INVALID;
else if($user->status == YumUser::STATUS_INACTIVE)
$this->errorCode=self::ERROR_STATUS_INACTIVE;
else if($user->status == YumUser::STATUS_BANNED)
$this->errorCode=self::ERROR_STATUS_BANNED;
else if($user->status == YumUser::STATUS_REMOVED)
$this->errorCode=self::ERROR_STATUS_REMOVED;
return !$this->errorCode;
}
}
class Users extends CActiveModel
{
const STATUS_INACTIVE = 0;
const STATUS_ACTIVE = 1;
const STATUS_BANNED = -1;
const STATUS_REMOVED = -2;
// some ..........
public static function encrypt($string = "")
{
$salt = 'salt';
$string = sprintf("%s%s%s", $salt, $string, $salt);
return md5($string);
}
}
check your security configuration for cookies and sessions.
disable session.use_only_cookies & session.cookie_httponly in php.ini
file.
in PHP.INI => session.use_only_cookies = 0