Neue Rituale Posted June 20, 2023 Share Posted June 20, 2023 Thanks for the great modules. Maybe this was answered, unfortunately I didn't find anything about it. How can I remove or overwrite the routes from "DefaultRoutes.php"? I have already tried it with this: $module = $this->wire('modules')->get('AppAPI'); $module->registerRoute( 'auth', [ ['OPTIONS', '', AppApiHelper::class, 'noEndPoint'], ['GET', '', AppApiHelper::class, 'noEndPoint'], ['POST', '', AppApiHelper::class, 'noEndPoint'], ['DELETE', '', AppApiHelper::class, 'noEndPoint'], ] ); Unfortunately, they are still accessible and functional. Link to comment Share on other sites More sharing options...
zoeck Posted June 21, 2023 Share Posted June 21, 2023 On 6/18/2023 at 1:46 AM, Sebi said: The overview page has a button to auto-generate an OpenAPI 3.0.3 json, that can be imported in tools like Postman or Swagger. I have one more small suggestion to improve the function a bit ? Just replace the complete if inside the execute-endpoints.php file: if ($action === 'action-get-openapi') { [...] } With this: if ($action === 'action-get-openapi') { header('Content-Type: application/json; charset=utf-8'); echo json_encode($openApiOutput, JSON_PRETTY_PRINT + JSON_UNESCAPED_SLASHES + JSON_UNESCAPED_UNICODE + JSON_UNESCAPED_LINE_TERMINATORS); die(); } So Tracy is disabled on output and via the browser you can save the file directly as json. And Thanks for this nice update ? @Sebi 1 1 Link to comment Share on other sites More sharing options...
eelkenet Posted September 7, 2023 Share Posted September 7, 2023 Hi @Sebi, I'm about to start work on a web-app that will (hopefully) use AppApi with 2-factor authentication, using the TOTP module from Ryan. I would like to use the Double JWT authentication for the most secure set-up. As I understand, this would currently not be possible, except maybe if I resort to PHP session instead and create my own login endpoint that implements some of the TfaTotp module methods. Is that correct? Or do you have any pointers as to how to implement this with Double JWT? Link to comment Share on other sites More sharing options...
rastographics Posted September 13, 2023 Share Posted September 13, 2023 For Double JWT approach, have you considered sending tokens to client using httpOnly cookie? I'm not an expert on this topic, but when researching to see where to save the tokens in my app, it seems the opinion for most secure involves httpOnly cookie (among other things). One such conversation:https://stackoverflow.com/questions/27067251/where-to-store-jwt-in-browser-how-to-protect-against-csrf?rq=1 Do you currently use localstorage on the browser? I'm creating a new app. Your module is awesome. But I'm wondering if localstorage is most secure on client? And how to do httpOnly cookie with this module? Link to comment Share on other sites More sharing options...
gerritvanaaken Posted September 25, 2023 Share Posted September 25, 2023 This may be a silly question, but I couldn’t access the payload/body of a POST request within the public static function. The $data variable only contains the path, but not the body of the request. My code goes like this: 'email' => [ ['OPTIONS', '', ['POST']], ['POST', '', Email::class, 'sendEmail'] ], class Email { public static function sendEmail ($data) { var_dump($data); // contains only path var_dump(wire('input')); // "post" data is null My goal here is, of course, to send an email from a JavaScript application, using my PW installation as proxy. Link to comment Share on other sites More sharing options...
gerritvanaaken Posted September 25, 2023 Share Posted September 25, 2023 Nevermind. My POST request had the wrong Content Type Header. Link to comment Share on other sites More sharing options...
eelkenet Posted October 6, 2023 Share Posted October 6, 2023 On 9/7/2023 at 12:25 PM, eelkenet said: Hi @Sebi, I'm about to start work on a web-app that will (hopefully) use AppApi with 2-factor authentication, using the TOTP module from Ryan. I would like to use the Double JWT authentication for the most secure set-up. I have moved away from the Double JWT solution for now, as PHP sessions seem to work fine for my application. Also I managed to implement TFA validation, by editing the `classes/Auth.php` file. That seemed to be the only way I could do so: I tried hooking into ___doLogin() but couldnt figure out the order of things. See below! So, I replaced line 164: $loggedIn = $this->wire('session')->login($user->name, $password); With // Add Tfa authentication through TfaTotp if ($user->hasTfa()) { $tfa = $user->hasTfa(true); // Get code from incoming data // This only works if credentials + 2FA get sent inside the body $code = null; if ( isset($data->tfacode) && !empty('' . $data->tfacode) ) { $code = $data->tfacode; } $settings = $tfa->getUserSettings($user); if ($code && $tfa->isValidUserCode($user, $code, $settings)) { $loggedIn = $this->wire('session')->login($user->name, $password); } else { throw new AuthException("Invalid TFA code", 401); } } else { $loggedIn = $this->wire('session')->login($user->name, $password); } And then added the 2FA in the body request: // inside a log-in method const credentials = { email: this.identification, password: this.password, tfacode: this.tfacode, }; const response = await fetch('/api/auth', { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': 'MY_API_KEY', }, body: JSON.stringify(credentials), }); if (response.ok) { return response.json(); } else { let error = await response.json(); throw new Error(JSON.stringify(error)); } I have also managed to do a proof of concept of a register route that works in combination with the TfaTotp module, but that needs some polishing. Update: I figured out that, in order to get be able to hook into Auth::doLogin, I needed to check the 'Deactivate URL Hook' toggle in the AppApi module settings. After doing so, I can now successfully hook and check for the Tfa, hurrah! // In ready.php wire()->addHookAfter('Auth::doLogin', function (HookEvent $event) { $log = wire('log'); $session = wire('session'); // Get the original return value of ___doLogin $originalReturnValue = $event->return; // Check if the original login was successful if (isset($originalReturnValue['username']) && !empty($originalReturnValue['username'])) { $username = $originalReturnValue['username']; $user = $event->wire('users')->get("name=$username"); // Check if the user has TFA activated if ($user->hasTfa()) { $tfa = $user->hasTfa(true); // Get code from incoming data // This only works if 2FA gets sent inside the body, along with password and username $data = $event->arguments(0); $code = null; if (isset($data->tfacode) && !empty('' . $data->tfacode)) { $code = $data->tfacode; } $settings = $tfa->getUserSettings($user); if ($code && $tfa->isValidUserCode($user, $code, $settings)) { $log->save("tfaLogin", "Tfa code = correct!"); $event->return = $originalReturnValue; } // Incorrect Tfa, sign out and throw 401 else { $log->save("tfaLogin", "Tfa code = incorrect, do not allow logging in"); $session->logout(); throw new AuthException("Code incorrect!", 401); } } // No Tfa enabled, sign out and throw 401 else { $log->save("tfaLogin", "User does not have Tfa enabled.. do not allow logging in!"); $session->logout(); throw new AuthException("TFA not enabled!", 401); } } }); Link to comment Share on other sites More sharing options...
rastographics Posted October 23, 2023 Share Posted October 23, 2023 @Sebiwould you be open to a pull request that adds a new setting? Access Token Expires In? I see that the access token uses the $config->sessionExpireInSeconds value for the access token expiration. However, using JWT, I would like to have a shorter (60 minutes) session, because of using the Refresh Token to keep things logged in. For the rest of my site (not using AppApi), the normal users I want to have 24 hour session, which I set with $config->sessionExpireInSeconds. There is already an Expires At setting in AppApi, for Refresh Token. Is it okay to add a second Expires At setting for Access Token, in case we want to set a different expiration from rest of site? Hope this makes sense? Link to comment Share on other sites More sharing options...
rastographics Posted October 23, 2023 Share Posted October 23, 2023 31 minutes ago, rastographics said: @Sebiwould you be open to a pull request that adds a new setting? Access Token Expires In? I see that the access token uses the $config->sessionExpireInSeconds value for the access token expiration. However, using JWT, I would like to have a shorter (60 minutes) session, because of using the Refresh Token to keep things logged in. For the rest of my site (not using AppApi), the normal users I want to have 24 hour session, which I set with $config->sessionExpireInSeconds. There is already an Expires At setting in AppApi, for Refresh Token. Is it okay to add a second Expires At setting for Access Token, in case we want to set a different expiration from rest of site? Hope this makes sense? For now I'm doing this on line 271 of AppApi/classes/Auth.php . But I have to be careful when updating the module now. /* ADDED TO GIVE JWT ACCESS TOKEN A DIFFERENT SESSION LENGTH THAN REGULAR SITE LOGINS */ $config = $this->wire('config'); $expireSeconds = $config->sessionExpireSeconds; if(isset($config->appApiSessionExpireSeconds)){ $expireSeconds = $config->appApiSessionExpireSeconds; } $apptoken->setExpirationTime(time() + $expireSeconds); Link to comment Share on other sites More sharing options...
gerritvanaaken Posted March 13 Share Posted March 13 Hallo, I have some problems with special characters in POST URLs. It’s awkward. These are my routes: ['OPTIONS', 'tasks/{city}/{employee}', ['GET']], ['GET', 'tasks/{city}/{employee}', Googledocs::class, 'fetchTasks'], ['OPTIONS', 'tasks/{city}/{employee}/{row}', ['POST']], ['POST', 'tasks/{city}/{employee}/{row}', Googledocs::class, 'putTasksRow'] Employees with an Umlaut, however, seem to confuse the path/method detection: GET https://myapi.com/api/docs/tasks/wuerzburg/Pia-Mäder (works) POST https://myapi.com/api/docs/tasks/wuerzburg/Pia-Mäder (works, but shouldn’t) POST https://myapi.com/api/docs/tasks/wuerzburg/Pia-Mader (error 405, as intended) POST https://myapi.com/api/docs/tasks/wuerzburg/Pia-Mäder/42 (error 405, but should work) POST https://myapi.com/api/docs/tasks/wuerzburg/Pia-Mader/42 (works) (Yes, I should be using PUT or PATCH instead of POST, but my hosting provider has – strangely enough – a problem with Umlauts as well, when they are in PUT requests. It doesn’t even start PHP in these cases and throws an 405 error from Apache) Link to comment Share on other sites More sharing options...
Jonathan Lahijani Posted April 26 Share Posted April 26 @Sebi Right now, it is possible to view the OpenAPI json by going to /admin/setup/appapi/endpoints/action-get-openapi/ I want to automate building html-based documentation with Redocly CLI based on that JSON data, however because how it is currently programmed, I can't use a script to cleanly grab that JSON nor is there a method that easily gets it in that format given how the code is structured (using the executeEndpoints method doesn't get the JSON in the same way and it relies on urlSegments). Is it possible to refactor the code / create a new method that would allow getting the OpenAPI JSON directly? Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now