Jump to content

psy

Members
  • Posts

    669
  • Joined

  • Last visited

  • Days Won

    9

Everything posted by psy

  1. Got completely stuck on some coding issues. As a last resort I started a conversation with ChatGPT (free version). I had 2 problems. Problem #1 took me & ChatGPT a while to solve but we got there in the end. Now working on Problem #2. Not yet solved but ChatGPT has given me some ideas. Here's how we ended up tonight: Not only did ChatGPT give me some great ideas, it was more polite, encouraging and patient than most people I know. πŸ˜πŸ˜‚
  2. Learn more in the README.md on the GitHub page at https://github.com/clipmagic/LoginPassKey Version 0.0.2Beta released on GitHub. This version is more stable delivers tighter security supports LoginRegisterPro Stay tuned πŸ™‚
  3. Hi Bernhard, it's a super feature for most applications but it doesn't work with http requests. The FE TracyDebugger bar script gets tagged onto the end of the request and results in a JSON error. It was Adrian's suggestion to monitor guest dumps in another window that saved me. I tested your hook is /site/ready.php and it worked a treat! I then went back to TracyDebugger to see how Adrian handled it and found the answer. The method wasn't ready. Lifted Adrian's code from TD and adjusted it to suit my needs, ie in TracyDebugger init(): // log requests for Request Logger $this->wire()->addHookAfter('ProcessWire::ready', function($event) { if(!method_exists($event->page, 'render')) { $event->page->addHookAfter('render', $this, 'logRequests'); } }); $this->wire()->addHookAfter('Page::logRequests', $this, 'logRequests'); Learning from the masters all the time πŸ™‚
  4. I think that's the problem. The hook is in the module init() but as the user is a guest, the autoloaded module isn't ready, even with the After ProcessWire::ready hook. The way I read the docs, autoloaded modules should be ready at this point. I'm obviously missing something. I tried a bd() call but the user isn't logged in. Will check again from an incognito window with the Tracy Debugger guest dumps in a window in which I'm logged in. Cheers to @adrian for this tip πŸ™‚
  5. Thanks @bernhard I was aiming to load some scripts and add some html programmatically via my module to the admin login screen. I saw your post about injecting module js via $config->scripts but I think it assumes the user is already logged in and all autoload modules are ready. I couldn't get it to fire on the admin login screen, even with an after ProcessWire::ready hook, as a guest user. If I can't achieve it programmatically via the module api, I can add the instructions to manually add the code to admin.php before the require($config->paths->core . "admin.php"); as per your suggestion
  6. I've tried all sorts of hooks, before & after in my module and checked out how other modules do stuff, including TraceDebugger, which inserts scripts very early in the process. Tracy is the only hook I've found that inserts scripts before the user logs in. I've tried "ProcessWire::ready" "Page::render" "AdminTheme::getExtraMarkup" My hooks never fire. I do not want to create a new AdminTheme or have to manually change any admin template files What I'm trying to achieve is that a Guest who lands on the admin login page sees some extra rendered HTML. Any suggestions? Found the answer by studying the code in TracyDebugger on how to load methods that aren't ready in an autoload module and with Bernhard's suggested hook. See below posts for more info.
  7. Hi @adrian thanks again for your guidance and patience. It was a configuration issue. Tracy has so many options it can be difficult to know what works. I mistakenly only had Tracy enabled for the Frontend so your instructions didn't make sense at first. Achieved what I need by: Enabling Tracy for the backend on a browser window in which I was logged in as 'admin' From that browser window, enabling 'Guest dumps' Loading the PW page as a guest in an incognito window and submitting the https request Reverting to the Tracy browser window, refreshing it and viewing the Guest dumps May seem obvious to those who know. πŸ€¦β€β™€οΈ
  8. Adam Blunt's https://processwire.com/modules/tfa-web-authn/ is amazing! My hat goes off to him for getting it to work. Sadly, his use of the lubuch library and the fact that he changed some of the core library code to work with PW, caused me to scratch it due to conflicts. Anyhoo, have moved on and getting closer to a front-end user passkey login without the lubuch code and no more corrupted sessions. One thing I'd like to know is how to use Tracy on the front end (guest or superuser) with https requests? Whenever I have TD enabled on the frontend as a guest, the request fails as it includes the Tracy FE javascript. Is this a TD configuration thing?
  9. Oh man, why didn't that show up in all my searches πŸ€¦β€β™€οΈ Will definitely investigate. I'm well down the path with lubuch now - may still have to scratch it - and have solved the issue with sessions simply by bypassing them during the registration process. It may come back to bite me later. Please do let me know if you recall the issue with corrupted sessions. Thanks again πŸ™‚
  10. Hi @adrian and thank you for the prompt reply. I agree, it's not Tracy. Tracy is simply reporting the problem. Yes, I'm trying to integrate the https://github.com/lbuchs/WebAuthn. It obviously needs a lot of custom code to 'ProcessWire' it. The 'challenge' is proving to be the challenge - pun intended! I'd also googled the incomplete object problem and could find nothing specific to ByteBuffer. Touch wood, I've not encountered the admin issue with the session ByteBuffer today. Other issues for sure. There's a lot of conversation between the server and browser that has to be 100% to get the certificate created. The weirdest thing is that the first time the session byte buffer is accessed, it's reported correctly. Subsequent bd()'s show that it's corrupted. The front end page submits to an api (page) that has a switch statement based on the page urlSegment 1 (route). (image deleted) The demo site at https://webauthn.lubu.ch/_test/client.html doesn't have these issues and it's all based on sessions, get variables, html & js being processed by PHP. πŸ€·β€β™€οΈ and not a question for you unless you have any ideas on what's going on.
  11. Hi @adrian Love TD and can't do without it. Unfortunately I found a conflict with a module I'm developing. The module calls on a library that uses a particular class type for a challenge. My module is frontend only, autload="template!=admin" and the FE works with TD using the native PHP $_SESSION. I had http errors using PW's $session. However, when I go to the admin, PW crashes spectacularly with: Disabling TD (putting a dot before the module name) is the only solution to access the admin area, but creates other problems. TD is still installed but inaccessible. Have tried namespacing the $session var, ie $session->setFor("myspace", "challenge", "my data") but it makes no difference. Turning off $config->debug resulted is a slightly less alarming Error 500. Any ideas on how to fix? Or maybe this is a question for @ryan as it's the admin core that spitting the error?
  12. Having an 'active' checkbox in a custom Configurable Module by default would be great. My solution is to use hooks that inhibit module behaviour rather than disabling the module. In the module's config fields, I create a checkbox with the name 'enable'. Then, in the module hooks: public function ready() { // use whatever Class::function you need $this->addHookAfter('Page::render', $this, 'myFunction'); } public function myFunction(HookEvent $event) { if(!$this->enable) return; // ... code to execute if enable is true } } It doesn't disable the module but bypasses it's other functions.
  13. @Robin S good pickup! Thanks. Will add logic to ensure the user has/has not specific user roles πŸ™‚ Example code updated.
  14. @ryan's ForgotPassword module has been in PW since Day Dot. It does it's job BUT it's onerous, especially for Frontend Users, eg those using LoginRegisterPro. My client, quite reasonably, wanted the FE users to be logged in automatically after a successful password reset. The module doesn't have many hooks. Here's one solution to automatically logging in frontend users after a successful password reset. In site/ready.php: // Force login after successful password reset $this->addHookAfter('ProcessForgotPassword::renderMessage', function(HookEvent $event) { $msg = $event->arguments(0); $input = wire('input'); $session = wire('session'); $pages = wire('pages'); $page = wire('page'); $users = wire('users'); $return = $event->return; // This uses the module's default text. // Adapt to suit on multi-language sites or if you want it to work for admins too if(stripos($msg, 'success') !== false && $page->template->name !== 'admin') { $userid = $input->get('u', 'int'); $user = $users->get($userid); // limit access to specific users or roles if(!$user->isSuperuser() && $user->hasRole('login-register')) { $session->forceLogin($user); $session->redirect($pages->get("name=mypage")->url); } } $event->return = $return; });
  15. Nervously! πŸ˜† On a more practical note, I built an import from CSV routine that imports data in batches and requires the ImportPagesCSV module. In client's case it was to import user data exported to CSV files from their accounting system. ImportCSVPages imports the CSV data to pages under page named "Imported Customers CSV". Hard set limit was 50 per run. In site/ready.php: // Turn imported CSV customer list to users $wire->addHookAfter('Pages::saved', function (HookEvent $event) { $pages = $event->object; $page = $event->arguments(0); if ($page->id !== 5251) return; // Import Customers - use your own Import data parent page if ($page->children->count === 0) return; $return = $event->return; $users = wire('users'); foreach($page->children('limit=50') as $child) { // check user not already created $childEmail = $child->email; $emailAlready = $users->get("email=$childEmail"); if($emailAlready->count > 0) { wire('log')->save('myclient', "User with email,". $child->email . " already exists"); continue; } $customer = new User(); $customer->of(false); $customer->template = 'reseller'; $customer->name = $child->name; $customer->parent = 1033; // change to the 'real' parent, eg products $customer->addRole('login-register'); $customer->pass = bin2hex(random_bytes(10)); $fields = $child->getFields(); foreach ($fields as $field) { $fieldName = $field->name; $customer->of(false); if ($customer->template->hasField($fieldName)) { $customer->set($fieldName, $child->$fieldName); } elseif ($field->children) { // for fields within fieldsets foreach ($field->children as $child) { $childName = $child->name; if ($customer->template->hasField($childName)) $customer->set($childName, $child->$childName); } } } if(!$customer->hasRole('login-register')) $customer->addRole('login-register'); $customer->save(); $pages->delete($child); } $event->return = $return; }); Having a hard limit of 50 helped if things went wrong and didn't trigger timeouts. Process is: Import the data under the "Imported Customers CSV" Check the data is OK If OK, edit and save the "Imported Customers CSV" page to invoke the hook If the import didn't work, I could easily delete all the child pages of "Imported Customers CSV", make adjustments and try again.
  16. Aware of that. Wanted to keep the explanation short. Good idea to limited the event_date start and end πŸ™‚
  17. This is a database call so you can't perform operations on the field name. Maybe something like (untested): $events = $pages->find("template=event, sort=event_date"); $eventMonth = new PageArray(); foreach($events as $event) { $eventDate = $event->date->format("m"); if($eventDate === $currentMonth) $eventMonth->add($event); }
  18. And the final piece of the puzzle, again thanks to @Robin S, in site/templates/admin.php, see this post: $wire->addHookAfter('AdminTheme::getExtraMarkup', function(HookEvent $event) { $scripts = wire('files')->render('inc/admin-tpl-hook'); $parts = $event->return; $parts['head'] .= $scripts; $event->return = $parts; });
  19. AFAIK, a PageFiles field shows all files, including file descriptions, tags, etc. The visibility option is for the entire field. It would be helpful to minimise the file list in admin to filename or custom fields, eg {basename} {modified}, only in the admin area similar to repeaters. A down arrow could expand individual file meta. When a page has lots of attached files, it's cumbersome to scroll through all the files with descriptions & tags when the field visibility is "Open".
  20. First time I've ever encountered this warning message and unsure how to resolve. Scenario: Customer is a long-time PW client in Australia who is moving to the UK. The web host created a new account hosted in Germany and copied all the AU files and DB to the new hosting account/location, Germany being their closest hosting centre to the UK. Time diff between Germany and UK is 1hr Time diff between Australia and Germany is 10hrs Site is working with new URL, etc The new PHP time zone needs to be "Europe/London" and $config->timezone is set to same Times are important as the client will be taking online appointment bookings. How do I match the DB time to the new UK time zone? Solution: In 'site/config.php' immediately after the database connection info: $config->dbInitCommand = "SET NAMES '{charset}', time_zone = 'Europe/London' "; Where {charset} can be utf8 or utf8mb4 depending on your setup
  21. Using v1.0.14 which fixes a problem for multi-language sites. Unfortunately it breaks single language sites as it assumes multi-language support is installed. Fix for me was: public function ___wakeupValue(Page $page, Field $field, $value) { $field = $field->getContext($page); $this->svg = $field->get("format") !== "gif"; $this->markup = $field->get("markup") === 1; $user = $this->user; $languages = null; if(wire('modules')->isInstalled("LanguagesSupport")) $languages = $user->isGuest() ? [$user->language] : $page->getLanguages(); $sources = $this->parseSources($page, $field); return $this->generateQRCodes($page, $sources, $languages);
  22. Installed RockFrontend for the first time on a client dev site. Great work @bernhard! Client (superuser) is happy with the ability to modify content on the fly from the frontend. Had a few issues however with FormBuilder conflicts. When I render a FormBuilder form on page via the api, and manually add its styles and scripts in the <head> tag, RFE js fails with RockFrondEnd not found. Worked around this by embedding the form via the api so no js conflicts How do I turn off LiveReload for a guest user? Another form is in a 'body' field that is ALFRED enabled, with FormBuilder Method A, see attached image. The LiveReload code still loads and screws the FormBuilder CSRF check even though the user is not logged in. Work around was to turn off CSRF Check on the form but would prefer to have it enabled. Using: PW: 3.0.237 RockFrontEnd: 3.18.2 FormBuilder: 0.5.5
  23. No question, ProcessWire is fabulous for developers and the suggestions above would make it even better. Customers who are not developers are increasingly giving me feedback about how unintuitive the backend admin/editor is, especially now with the proliferation of DIY pagebuilders. Clients don't understand or care about the consequences. They care about not having to learn code to easily update their sites. They want the backend to look similar to the frontend, the convenience of doing it themselves without having to pay a developer. Too bad if the site doesn't work on all screen sizes, light/dark modes, isn't accessible, the home page looks like a ransom note, whatever. They genuinely don't like the default PW admin UI/UX. Pagegrid and RockPageBuilder modules are leading the way to solve this issue. Kudos to both developers BUT the modules are premium while a WP site gives customers basic WYSIWG page editing out of the box. My vote is to overhaul the admin UI/UX to make editing pages more WYSIWIG.
  24. Agree with @BrendonKoz. A vertical list on mobile is boring and no one scrolls on a carousel. The thing that has worked best for me is to shuffle the list. This has several benefits: No sponsor can complain their logo isn't visible - all have an equal opportunity Page content is constantly fresh which keeps the search engines happy Maybe on mobile have a small number of random logos on the home page/footer and a button linking to a sponsor list page. Have clients take this one step further and give each sponsor a dedicated page after clicking on their logo. Again this has worked well for SEO especially when the sponsor shared their page on their socials.
Γ—
Γ—
  • Create New...