Skip to content
This repository has been archived by the owner on Jan 6, 2023. It is now read-only.

Commit

Permalink
Merge branch 'v8.0.0' of https://github.com/directus/api into v8.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
binal-7span committed Nov 12, 2019
2 parents 379457d + 0629167 commit 3ba3708
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 71 deletions.
35 changes: 20 additions & 15 deletions src/core/Directus/Services/AuthService.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace Directus\Services;

use function Directus\get_directus_path;
use function Directus\get_api_project_from_request;
use function Directus\get_url;
use Directus\Authentication\Exception\ExpiredRequestTokenException;
use Directus\Authentication\Exception\InvalidRequestTokenException;
use Directus\Authentication\Exception\InvalidTokenException;
Expand Down Expand Up @@ -68,22 +71,22 @@ public function loginWithCredentials($email, $password, $otp=null, $mode = null)
$tfa_enforced = $usersService->has2FAEnforced($user->getId());

switch($mode){
case DirectusUserSessionsTableGateway::TOKEN_COOKIE :
case DirectusUserSessionsTableGateway::TOKEN_COOKIE :
$user = $this->findOrCreateStaticToken($user);
$responseData['user'] = $user;
break;
case DirectusUserSessionsTableGateway::TOKEN_JWT :
default :
case DirectusUserSessionsTableGateway::TOKEN_JWT :
default :
$token = $this->generateAuthToken($user);
$user = $user->toArray();
$responseData = [
'token' => $token,
'user' => $user
];

}
$responseObject['data'] = $responseData;

if(!is_null($user)){
$needs2FA = $tfa_enforced && $user['2fa_secret'] == null;
if($needs2FA){
Expand All @@ -100,7 +103,7 @@ public function loginWithCredentials($email, $password, $otp=null, $mode = null)
* @param array $user
*
* @return array
*
*
*/
public function findOrCreateStaticToken(&$user)
{
Expand Down Expand Up @@ -227,12 +230,12 @@ public function handleAuthenticationRequestCallback($name, $generateRequestToken
$user = $this->authenticateWithEmail($serviceUser->getEmail());

switch($mode){
case DirectusUserSessionsTableGateway::TOKEN_COOKIE :
case DirectusUserSessionsTableGateway::TOKEN_COOKIE :
$user = $this->findOrCreateStaticToken($user);
$responseData['user'] = $user;
break;
case DirectusUserSessionsTableGateway::TOKEN_JWT :
default :
case DirectusUserSessionsTableGateway::TOKEN_JWT :
default :
$token = $generateRequestToken ? $this->generateRequestToken($user) : $this->generateAuthToken($user);
$responseData = [
'token' => $token,
Expand All @@ -258,7 +261,7 @@ public function authenticateWithToken($token, $ignoreOrigin = false)
} else {
$authenticated = $this->getAuth()->authenticateWithPrivateToken($token);
}

return $authenticated;
}

Expand Down Expand Up @@ -384,6 +387,7 @@ public function generateRequestToken(UserInterface $user)
* @param $email
*/
public function sendResetPasswordToken($email)

{
$this->validate(['email' => $email], ['email' => 'required|email']);

Expand All @@ -393,10 +397,14 @@ public function sendResetPasswordToken($email)

$resetToken = $auth->generateResetPasswordToken($user);

\Directus\send_forgot_password_email($user->toArray(), $resetToken);
// Sending the project key in the query param makes sure the app will use the correct project
// to send the new password to
$resetUrl = get_url() . 'admin/#/reset-password?token=' . $resetToken . '&project=' . get_api_project_from_request();

\Directus\send_forgot_password_email($user->toArray(), $resetUrl);
}

public function resetPasswordWithToken($token)
public function resetPasswordWithToken($token, $newPassword)
{
if (!JWTUtils::isJWT($token)) {
throw new InvalidResetPasswordTokenException($token);
Expand Down Expand Up @@ -427,12 +435,9 @@ public function resetPasswordWithToken($token)
throw new InvalidResetPasswordTokenException($token);
}

$newPassword = StringUtils::randomString(16);
$userProvider->update($user, [
'password' => $auth->hashPassword($newPassword)
]);

\Directus\send_reset_password_email($user->toArray(), $newPassword);
}

public function refreshToken($token)
Expand Down
37 changes: 25 additions & 12 deletions src/endpoints/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Directus\Application\Route;
use function Directus\array_get;
use function Directus\get_directus_setting;
use function Directus\get_directus_path;
use function Directus\get_project_session_cookie_name;
use function Directus\get_request_authorization_token;
use function Directus\encrypt_static_token;
Expand Down Expand Up @@ -36,7 +37,7 @@ public function __invoke(Application $app)
$app->post('/logout/{user}', [$this, 'logoutFromAll']);
$app->post('/logout/{user}/{id}', [$this, 'logoutFromOne']);
$app->post('/password/request', [$this, 'forgotPassword']);
$app->get('/password/reset/{token}', [$this, 'resetPassword']);
$app->post('/password/reset', [$this, 'resetPassword']);
$app->post('/refresh', [$this, 'refresh']);
$app->get('/sso', [$this, 'listSsoAuthServices']);
$app->post('/sso/access_token', [$this, 'ssoAccessToken']);
Expand Down Expand Up @@ -255,7 +256,8 @@ public function resetPassword(Request $request, Response $response)
$authService = $this->container->get('services')->get('auth');

$authService->resetPasswordWithToken(
$request->getAttribute('token')
$request->getParsedBodyParam('token'),
$request->getParsedBodyParam('password')
);

return $this->responseWithData($request, $response, []);
Expand Down Expand Up @@ -291,10 +293,10 @@ public function listSsoAuthServices(Request $request, Response $response)
{
/** @var AuthService $authService */
$authService = $this->container->get('services')->get('auth');

/** @var Social $externalAuth */
$externalAuth = $this->container->get('external_auth');

$services = [];
foreach ($externalAuth->getAll() as $name => $provider) {
$services[] = $authService->getSsoBasicInfo($name);
Expand Down Expand Up @@ -367,18 +369,22 @@ public function ssoServiceCallback(Request $request, Response $response)
{
/** @var AuthService $authService */
$authService = $this->container->get('services')->get('auth');

$session = $this->container->get('session');
// TODO: Implement a pull method
$redirectUrl = $session->get('sso_origin_url');
$session->remove('sso_origin_url');
$mode = $session->get('mode');

$redirectUrl = $mode == DirectusUserSessionsTableGateway::TOKEN_COOKIE
? get_directus_path() . '/admin/#/'
: $session->get('sso_origin_url');

$needs2FA = false;
$responseData = [];
$urlParams = [];

try {
$responseData = $authService->handleAuthenticationRequestCallback(
$request->getAttribute('service'),
!!$redirectUrl,
true,
$mode
);

Expand All @@ -388,6 +394,7 @@ public function ssoServiceCallback(Request $request, Response $response)
if($tfa_enforced || !is_null($responseData['data']['user']['2fa_secret'])){
throw new SsoNotAllowedException();
}

switch($mode){
case DirectusUserSessionsTableGateway::TOKEN_COOKIE :
$response = $this->storeCookieSession($request,$response,$responseData['data']);
Expand All @@ -410,7 +417,7 @@ public function ssoServiceCallback(Request $request, Response $response)
$urlParams['error'] = true;
}


if ($redirectUrl) {
$redirectQueryString = parse_url($redirectUrl, PHP_URL_QUERY);
$redirectUrlParts = explode('?', $redirectUrl);
Expand All @@ -419,10 +426,16 @@ public function ssoServiceCallback(Request $request, Response $response)
if (is_array($redirectQueryParams)) {
$urlParams = array_merge($redirectQueryParams, $urlParams);
}
$urlToRedirect = !empty($urlParams) ? $redirectUrl . '?' . http_build_query($urlParams) : $redirectUrl;
$response = $response->withRedirect($urlToRedirect);

if (!empty($urlParams) && $mode == DirectusUserSessionsTableGateway::TOKEN_COOKIE) {
$redirectUrl .= 'login?' . http_build_query($urlParams);
} else {
$redirectUrl .= '?' . http_build_query($urlParams);
}

$response = $response->withRedirect($redirectUrl);
}else{
$response = $response->withRedirect('/admin');
$response = $response->withRedirect($redirectUrl);
}

$session->remove('mode');
Expand Down
2 changes: 1 addition & 1 deletion src/endpoints/Home.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Home extends Route
{
public function __invoke(Request $request, Response $response)
{
$response = $response->withRedirect('/admin');
$response = $response->withRedirect('./admin/');
return $this->responseWithData($request, $response, []);
}
}
28 changes: 3 additions & 25 deletions src/helpers/mail.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,42 +135,20 @@ function parse_twig($viewPath, array $data)
}
}

if (!function_exists('send_reset_password_email')) {
/**
* Sends a new password email
*
* @param $user
* @param string $password
*/
function send_reset_password_email($user, $password)
{
$data = [
'new_password' => $password,
'user_full_name' => get_user_full_name($user),
];
send_mail_with_template('reset-password.twig', $data, function (Message $message) use ($user) {
$message->setSubject(
sprintf('New Temporary Password: %s', get_directus_setting('project_name', ''))
);
$message->setTo($user['email']);
});
}
}

if (!function_exists('send_forgot_password_email')) {
/**
* Sends a new reset password email
*
* @param array $user
* @param string $token
*/
function send_forgot_password_email(array $user, $token)
function send_forgot_password_email(array $user, $url)
{
$data = [
'reset_token' => $token,
'reset_url' => $url,
'user_full_name' => get_user_full_name($user),
];
send_mail_with_template('forgot-password.twig', $data, function (Message $message) use ($user) {
send_mail_with_template('reset-password.twig', $data, function (Message $message) use ($user) {
$message->setSubject(
sprintf('Password Reset Request: %s', get_directus_setting('project_name', ''))
);
Expand Down
13 changes: 0 additions & 13 deletions src/mail/forgot-password.twig

This file was deleted.

8 changes: 3 additions & 5 deletions src/mail/reset-password.twig
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@

<p>Hey {{ user_full_name }},</p>

<p>Here is a temporary password to access Directus:</p>
<p>You requested to reset your password, click here to reset your password:</p>

<p>{{ new_password }}</p>
<p><a href="{{ reset_url }}">Reset my password</a></p>

<p>Once you log in, you can change your password via the User Settings menu.</p>

<p>Love,<br>Directus</p>
<p> Love,<br>Directus</p>

{% endblock %}

0 comments on commit 3ba3708

Please sign in to comment.