Commit graph

1779 commits

Author SHA1 Message Date
7f4c34ff6a Oops, stop requiring a new password whenever AuthUser is changed
Ah right, I went and checked the Devise source code, and the default
implementation for `password_required?` is a bit trickier than I
expected:

```ruby
def password_required?
  !persisted? || !password.nil? || !password_confirmation.nil?
end
```

Looks like `super` does a good enough job here, though! (I'm actually
kinda surprised, I wasn't sure how Ruby's `super` rules worked, and
this isn't a subclass thing—or maybe it is, maybe the `devise` method
adds a mixin? Idk! But it does what I expect, so, great!)

So now, we require the password if 1) Devise doesn't see a UI reason
not to, *and* 2) the user isn't using OmniAuth (i.e. NeoPass).

This had caused a bug where it was impossible to use the Settings page
*without* changing your password! (The form says it's okay to leave it
blank, which stopped being true! But now it's fixed!)
2024-03-14 19:20:33 -07:00
3eeb5d1065 Actually create user from NeoPass authentication! <3 <3
Whew, exciting! Still done nothing against the live NeoPass server, but
we've got this fully working with the development server, it seems!
Wowie!!

This is all still hidden behind secret flags, so it's fine to deploy
live. (And it's not actually a problem if someone gets past to the
endpoints behind it, because we haven't actually set up real
credentials for our NeoPass client yet, so authentication will fail!)

Okay time to lie down lol.
2024-03-14 19:11:06 -07:00
31a11a04fa Read and customize the username reported by neopass-server
Okay, `sub` seems to be a pretty standard place for user identifiers.
Let's start with that assumption! I override the `oauth2-mock-server`'s
default of `johndoe` with `theneopetsteam`, just to be cute :3
2024-03-14 18:19:45 -07:00
9cbeee0acd Refactor to use OpenID Connect OmniAuth gem instead of plain OAuth2
Right, I didn't totally connect the dots that there's some OpenID
features in the mix here for how we expect to identify the user once
they authenticate. It requires looking up the provider's public key,
and validating the JWT they sent us. This gem does all that for us!

I don't actually know what a real NeoPass `id_token` looks like yet?
But I'll fill in some placeholder stuff for now, and use that for
initializing the account!
2024-03-14 18:11:40 -07:00
ffcfce2eb8 Use local-only HTTPS certs for the development neopass-server
I'm starting to work with the OpenID Connect stuff in NeoPass, and the
library I'm using for discovery doesn't seem to want to do it over a
plain `http://` connection. (I dug into the source files, and it just
actually is hardcoded to only work with HTTPS, as far as I can tell?)

So, I've added logic to `neopass-server` to try to make an HTTPS
certificate with the `mkcert` utility (if installed), which is a tool
that installs a root certificate authority on your local machine, then
helps you create certificates via that authority that will work only on
your local machine.

I think I'll also be able to remove the "main" server in front of the
backing server, because the library I'm using now will be able to
"discover" the auth and token endpoints, so it won't matter that our
local one uses different URLs than live NeoPass does? We'll find out!

I also remove `neopass-server` from the `Procfile`, because I think
it's a bit rude to have it auto-try to run `mkcert`. We could like,
make the process just a no-op in that case? But I think I'd prefer to
just run `neopass-server` by hand when I want it, for simplicity.
2024-03-14 18:01:54 -07:00
21bc4bcadc Fix neopass-server to respond correctly to /token requests
Hey nice, now we can actually get a round-trip auth success! This gets
us to the `Devise::OmniauthCallbacksController#neopass` success method,
so now we need to add our logic to actually login/signup!
2024-03-14 16:26:43 -07:00
f483722af4 NeoPass strategy interacts with dev NeoPass server, which is still WIP
In this change, we wire up a new NeoPass OAuth2 strategy for OmniAuth,
and hook up the "Log in with NeoPass" button to use it!

The authentication currently fails with `invalid_credentials`, and
shows the `owo` response we hardcoded into the NeoPass server's token
response. We need to finally follow up on the little `TODO` written in
there!
2024-03-14 16:13:31 -07:00
77057fe6a2 Add hidden "Log in with NeoPass" button, to placeholder login strategy
If you pass `?neopass=1` (or a secret value in production), you can see
the "Log in with NeoPass" button, which currently takes you to
OmniAuth's "developer" login page, where you can specify a name and
email and be redirected back. (All placeholder UI!)

We're gonna strip the whole developer strategy out pretty fast and
replace it with one that uses our NeoPass test server. This is just me
checking my understanding of the wiring!
2024-03-14 15:34:24 -07:00
08b1b9e83b Add OmniAuth plugin to AuthUser
This is setting us up for NeoPass, but first we're just gonna try stuff
with the "developer" strategy that's built in for testing, rather than
using the NeoPass dev server!
2024-03-14 15:06:13 -07:00
58e6b46b42 Split NeoPass dev server into main/backing servers 2024-03-14 15:06:13 -07:00
e04387a533 Also run neopass-server as part of bin/dev
Now, running `bin/dev` will also run `bin/neopass-server`, to make it
easier to Just Do It for testing NeoPass!
2024-03-14 15:06:13 -07:00
0db7d3f966 WIP: Add bin/neopass-server as test NeoPass server implementation
Just a little mock server for use in development! Not referenced by
anything yet.
2024-03-14 15:06:13 -07:00
3bf3eaac8a Fix scoping on CSS for donate page
Oh right, all these cute overrides should be scoped to the page!

I guess we skipped this because we had pulled this out into a
separate stylesheet. Curiously learning more about how Turbo handles
this kind of thing, like that it doesn't *unload* stylesheets that
*leave* the page when you navigate!
2024-03-13 22:13:16 -07:00
c3eab22b4e Downgrade jQuery on homepage to be the same version as everywhere else
I noticed an issue where Turbo-loading between the Your Items page and
the homepage would clobber each other's copy of jQuery, breaking things
sometimes. e.g. go to Your Items, then go to home, then go to Your
Items, and the page's JS fails because `$.fn.live` isn't defined.

I briefly tested the homepage and it didn't seem to actually depend on
any features from the later version of jQuery? At least not that I
noticed! So I'll just downgrade for consistency. (I also tried
upgrading the Your Items page, but there's too much usage of
`$.fn.live`, which is replaced with a notably different syntax in
jQuery 2.0+.)
2024-03-13 21:38:45 -07:00
c011e99819 Fix various JS Turbo issues
First one, Turbo reasonably yelled at us in the JS console that we
should put its script tag in the `head` rather than the `body`, because
it re-executes scripts in the `body` and we don't want to spin up Turbo
multiple times!

I also removed some scripts that aren't relevant anymore, fixed a bug
in `outfits/new.js` where failing to load a donation pet would cause
the preview thing to not work when you type (I think this might've
already been an issue?), reworked `item_header.js` to just run once in
the `head`, and split scripts into `:javascripts` (run once in `head`)
vs `:javascripts_body` (run every page load in `body`).
2024-03-13 21:26:22 -07:00
40804c1543 Fix the Chakra CSS reset applying to too many things on item page
Finally getting around to this because, with Turbo in play, it applies
to subsequent *pages* too, oops! Previously we at least had the blast
radius of this known issue constrained to the item page itself lol :p
2024-03-13 20:57:30 -07:00
d118d185e2 Add more NeoPass details to about page
Got some questions in Discord about account unlinking, and seeing
people look ahead to other potential integrations. Want to clarify that
unlinking will work here (barring any surprises!), and that there's no
data sharing _just_ yet!
2024-03-13 17:55:23 -07:00
7515527555 Oops, add ActionCable back to the app
Turbo expects this to exist, for features we don't use! I didn't bother
to check if Turbo has a way to turn this off too, I just said fine lol

Turbo worked in development without this because it only loads files as
needed, whereas in production it blocked the app from starting up. But
you can see the error in development by running `rails zeitwerk:check`,
which attempts to preload everything to make sure it all works, and you
get this:

```
NameError: uninitialized constant ActionCable (NameError)

class Turbo::StreamsChannel < ActionCable::Channel::Base
```

Fixed now!
2024-03-13 17:48:25 -07:00
75418339da Add DTI 2020 link to item pages
Someone requested this in Discord, and I figured why not! I'm still
planning to move stuff away from Impress 2020 over time, I just figure
may as well have them more linked while this is still The Reality
2024-03-13 17:46:45 -07:00
9295ae75ad Add the full ".html.haml" extension to "_item_header.haml"
This doesn't really matter, I just didn't realize the `.html` part was
optional, and I guess I omitted it here without realizing? But let's
add it for consistency.
2024-03-13 17:35:25 -07:00
01f9065dbd Fix incorrect closet list deletion prompt message
It's no longer true that we transfer the items to the default list; we
just delete them now!
2024-03-13 13:59:27 -07:00
5631b02157 Fix confirmation prompts for various actions
These were depending on the `rails-ujs` scripts we haven't had in here
for a while! Now, they use the new equivalent Turbo attributes.
2024-03-13 13:56:10 -07:00
9fe44e3f91 Hack to speed up loading the homepage
The modeling code is slow! I think in production it's being cached, and
tbh I though I had development mode caching turned on over here, but
it's quite evidently _not_ doing it if so, so. Okay! Skip for now.
2024-03-13 13:51:28 -07:00
684dcb53ba Add Turbo to speed up the app, and set up for missing UJS features
Oh right, we don't have Rails UJS going on anymore, which is what
handled the confirmation prompts for deleting lists. Turbo is the more
standard modern solution to that, and should speed up certain
pageloads, so let's do it!

Here I install the `turbo-rails` gem, then run `rails turbo:install` to
install the `@hotwired/turbo-rails` npm package. Then I move
`application.js` that's run all on pages but the outfit editor into our
section of JS that gets run through the bundler, and add Turbo to it.

I had to fix a couple tricky things:

1. The outfit editor page doesn't play nice with being swapped into the
   document, so I make it require a full page reload instead.
2. Prefetching the Sign In link can cause the wrong `return_to` address
   to be written to the `session`. (It's a GET request that does, ever
   so slightly, take its own actions, oops!) As a simple hacky answer,
   we disallow prefetching on that link.

Haven't fixed up the UJS stuff for confirm prompts to use Turbo yet,
that's next!
2024-03-13 13:43:48 -07:00
b39542a2ba Merge branch 'about-neopass' 2024-03-13 12:22:32 -07:00
6a347bd733 Add "Posted" date to NeoPass announcement 2024-03-13 12:22:15 -07:00
b388486676 Add NeoPass announcement banner to homepage 2024-03-13 12:20:38 -07:00
3f172b91c5 Oops, fix redirect to item thumbnail
This `.gif` format is used in the items list "export to petpage"
feature, as the image URL for items whose URLs are known to contain
blocked words that prevent them from being used in petpages.

But when doing some Rails upgrade long ago, we didn't notice the new
security feature that blocks redirects to other sites without a special
flag being set. It was triggering 500 errors, oops.

Now, we set the flag!
2024-03-12 18:45:05 -07:00
3bf07b02da A few more NeoPass about page copy edits 2024-03-12 18:41:58 -07:00
4bff5b7943 Oops, add dimensions to NeoPass header image
Always forget about this! Lol
2024-03-12 18:41:44 -07:00
ba859ce747 Oops, fix neopass-header.png image reference
Huh, omitting the filetype is legal in development, but failed in
production. Weird!
2024-03-12 18:34:40 -07:00
640e0423a7 Copy edits, mostly bolding sections of the NeoPass about page 2024-03-12 18:21:23 -07:00
0e7457980f Add NeoPass header image 2024-03-12 18:20:57 -07:00
022286a746 Add first draft of /about/neopass page 2024-03-12 17:58:44 -07:00
2cfcfaf69d Rename StaticController to AboutController
This is where `/about` pages will go now!
2024-03-12 17:12:43 -07:00
9aef987f95 Move partials in views/static to views/application
I think this is the more canonical place for stuff like this these days!
It's nice to be able to just say the short name when calling `render`.

Here's the answer I looked up about it: https://stackoverflow.com/a/9892081/107415

My immediate motivation is that I'm looking at creating more About
pages, and thinking about where to put them; I think maybe we trash the
`StaticController`, move these partials out to here, and move terms
into a new `AboutController`?
2024-03-10 18:48:25 -07:00
cf6921329d Oops, choose the *first* PNG from the manifest, to avoid reference art
When we moved more logic into the main app, we made some assumptions
about manifest art that were different than Impress 2020's, in hopes
that they would be More Correct for potential future edge cases.

Turns out, they were actually *less* correct for *current* edge cases!
Chips linked us to a few examples, including this Reddit post:

https://www.reddit.com/r/neopets/comments/1b8fd72/i_dont_think_thats_the_correct_image/

Fixed now!
2024-03-07 14:16:05 -08:00
e1a5eaeb68 Install cron job to run rails public_data:commit weekly in production
The Sunday 1:15am time was chosen pretty arbitrarily; I think having it
happen at a "start of week" kind of weekday is clarifying for weekly
tasks, but I chose ":15" mostly to mitigate that thing where cron jobs
all run on the hour at the same time, while still feeling normal :p
2024-03-01 13:20:59 -08:00
98dd9ec782 Create rails public_data:pull task, to load up the latest public data
Yay, it works! Easy peasy! Love this way of integrating shell and Ruby,
it's cute!
2024-03-01 13:18:58 -08:00
8dc11f9940 Create rails public_data:commit task, to share public data dumps
I'm starting to port over the functionality that was previously just,
me running `yarn db:export:public-data` in `impress-2020` and
committing it to Git LFS every time.

My immediate motivation is that the `impress-2020` git repository is
getting weirdly large?? Idk how these 40MB files have blown up to a
solid 16GB of Git LFS data (we don't have THAT many!!!), but I guess
there's something about Git LFS's architecture and disk usage that I'm
not understanding.

So, let's move to a simpler system in which we don't bind the public
data to the codebase, but instead just regularly dump it in production
and make it available for download.

This change adds the `rails public_data:commit` task, which when run in
production will make the latest available at
`https://impress.openneo.net/public-data/latest.sql.gz`, and will also
store a running log of previous dumps, viewable at
`https://impress.openneo.net/public-data/`.

Things left to do:
1. Create a `rails public_data:pull` task, to download `latest.sql.gz`
   and import it into the local development database.
2. Set up a cron job to dump this out regularly, idk maybe weekly? That
   will grow, but not very fast (about 2GB per year), and we can add
   logic to rotate out old ones if it starts to grow too far. (If we
   wanted to get really intricate, we could do like, daily for the past
   week, then weekly for the past 3 months, then monthly for the past
   year, idk. There must be tools that do this!)
2024-02-29 14:30:33 -08:00
88c98f2023 Update GitHub links to point to our self-hosted OpenNeo Code 2024-02-29 11:24:21 -08:00
9156fa7162 Bold the Terms of Use link when it's been changed recently 2024-02-29 11:22:12 -08:00
0316544e32 Update Terms of Use
Mostly pulled from Impress 2020, but with some copy edits, and AI
clauses added for good measure.
2024-02-29 11:21:53 -08:00
b7a4bb988b Remove unused static/terms stylesheet
This gets put into the application stylesheet because of our silly way
of doing stylesheets. Let's have it begone!
2024-02-29 10:53:06 -08:00
ec6dca1c16 Improve Unicode support, emojis don't crash us anymore lol!
A few pieces here:

1. Convert all tables to `utf8mb4`+`utf8mb4_unicode_520_ci` strings.
2. Configure that as the server's default.
3. Configure the Rails database connection to use this encoding too.

Came together pretty well, whew! This has been a LONG time coming,
`latin1` is NOT a good charset for the year 2024!
2024-02-28 18:54:27 -08:00
8f78892212 Remove item_translations from schema.rb??
Yeah what the heck, why is this here, we have the migration to drop it
and it's already dropped in production!

Y'know, sometimes I goof a migration and it sets things in a weird
state in development, maybe we didn't recover correctly from that or
something? But idk how we would have goofed this one. Whatever! I've
manually dropped it from my development machine, and it was already
correctly dropped on production, so, go figure!
2024-02-28 18:53:48 -08:00
371da73615 Revert "Oops, add AltStyle#series_name db change to schema"
This reverts commit cc339672b1.

Oh, wait, no, the state the schema file was in *was* correct. I'm not
sure why… huh ok, I need to debug my local state.
2024-02-28 17:20:43 -08:00
cc339672b1 Oops, add AltStyle#series_name db change to schema
Did we end up behind on this migration in development? Idk! Weird! I'm
doing other migration stuff now and noticing this change slipping in
and I'm like. Huh! You should've already been there!
2024-02-28 15:53:48 -08:00
bc8d265672 Add handlers for requests that were stopped during the reboot process
According to our GlitchTip error tracker, every time we deploy, a
couple instances of `Async::Stop` and `Async::Container::Terminate`
come in, presumably because:

1. systemd sends a STOP signal to the `falcon host` process.
2. `falcon host` gives the in-progress requests some time to finish up
3. Sometimes some requests take too long, and so something happens.
   (either a timer in Falcon or a KILL signal from systemd, not sure!)
   that leads the ongoing requests to finally be terminated by raising
   an `Async::Stop` or `Async::Container::Terminate`. (I'm not sure
   when each happens, and maybe they happen at different points in the
   process? Maybe one happens for the actual long-running ones, vs the
   other happens if more requests come in during the meantime but get
   caught in the spin-down process?)
4. Rails bubbles up the errors, our Sentry library notices them and
   sends them to GlitchTip, the user presumably receives the generic
   500 error, and the app can finally close down gracefully.

It's hard for me to validate that this is *exactly* what's happening
here or that my mitigation makes sense, but my logic here is basically,
if these exceptions are bubbling up as "uncaught exceptions" and
spamming up our error log, then the best solution would be to catch
them!

So in this change, we add an error handler for these two error classes,
which hopefully will 1) give users a better experience when this
happens, and 2) no longer send these errors to our logging 🤞️

That strange phenomenon where the best way to get a noisy bug out of
your logs is to fix it lmao
2024-02-28 13:50:13 -08:00
522287ed53 Fix MissingAttributeError in ClosetHanger#merge_quantities
Oh rough, when moving an item list entry from one list to another, our
logic to merge their quantities if it's already in that list was just
fully crashing!

That is, moves without anything to merge were working, but moves that
required a merge were raising Internal Server Error 500, because the
`list_id` attribute wasn't present.

I'm not sure why this ever worked, I'm assuming using `list_id` in the
`where` condition would include it in the `select` implicitly in a
previous version of Rails? Or maybe Rails used to have fallback
behavior to run a second query, instead of raising
`MissingAttributeError` like it does now?

Well, in any case, this seems to fix it! Whew!
2024-02-28 13:30:55 -08:00