Age | Commit message (Collapse) | Author |
|
Include the new step 2 of installation, starting the program with `brew
services`.
After the license has been added, the daemon must be restarted in order
for the license to be recognised.
|
|
License the software with the GNU AGPLv3+ with the exception of the
'aquatic-prime' and 'paddle' libraries and 'aquatic-prime' binary, which
are licensed under the GNU GPLv3+.
|
|
Forgot to change this when I changed the function signature.
|
|
For whatever reason, the environment variables in my `.htaccess` weren't
getting passed to my FastCGI executables on my production server.
Wasn't sure how to get them passed to the programs, so decided instead
to compile the env variables into the binaries.
To do that, we source the environment file before building the release
builds in the Docker container.
|
|
Renames the binary. The name "license-generator" no longer seems apt at
this point. That binary doesn't actually generate a license, it serves
as the webhook endpoint for Paddle's license fulfillment. Our `license`
binary handles the actual license generation.
The URL I'll be using for the webhook is `/fulfillment`, so this also
makes sense from that perspective.
|
|
Add the instructions we put in the fulfillment email to the
thank-you/license download page. Want to make sure buyers know how to
license the software after purchasing it.
Rephrase the install text to be simpler and more to the point.
|
|
Include install and license instructions in the purchase fulfillment
email.
|
|
Paddle will take the text from the response of this endpoint and include
it in the purchase fulfillment email to a customer.
Include the URL for the purchaser to download their license. Use the
'url' crate's parser to build the URL in order to URL-escape special
characters.
Honestly I'd rather have had a system where the license file gets
included in the receipt email. Unfortunately, with the Paddle
fulfillment mechanism I'm using, we can only send text. I learned after
building the download endpoint that I could manage fulfillment myself.
This would require me to listen to an "alert"-type Paddle webhook, and
send the email myself (which would include the license file). Since I
already built the license download page, I decided to just use it
instead of doing the emailing. Also, my web host limits my SMTP usage,
so there could be issues there. I'd have to do the emailing in a
separate batch process instead of in the webhook handler to ensure that
no emails would get dropped.
|
|
Move the existing thank-you page to `thank-you-license-download.html`.
Use `thank-you.html` as the final page of the purchase flow. Paddle will
redirect to this page at the end of purchase. Allows us to retain some
branding during purchase.
Using the existing HTML file for a better URL.
|
|
Done already.
|
|
Trying to add a little more entropy to the calculation.
Went with chrono instead of `std::time` because it gives me an `i64`
timestamp instead of a `Result`.
|
|
|
|
|
|
HTML copied from the 404 page, but I remove the `text-center` on the
error message because it doesn't look good. Took a multiline message for
me to realise it.
|
|
The `set_404()` function doesn't do this, as it makes no assumptions
about response content type.
|
|
The `REQUEST_URI` parameter gives us the URL path including the query
string. Unfortunately, there's no param for just the path without the
query string. Well, that's not entirely true. On my production server
I'll be using Apache, and in development I'm using Lighttpd. Apache
provides a `SCRIPT_URL` param that does include just the path, but
Lighttpd doesn't appear to have an equivalent.
I wasn't able to figure out how to add a `SCRIPT_URL` param in Lighttpd
manually, either. Using `bin-environment` in the FastCGI config didn't
work, and using `setenv.add-environment` wouldn't allow me to set it to
both of our routes (I assume).
In light of this, just grab the path from `REQUEST_URI` by getting the
part in front of `?`.
|
|
The query string is already included in the `REQUEST_URI` param. What we
had would just print it twice.
|
|
|
|
I want to be able to use the exact same logic for the `/license` route.
To do so, we move the common logic to a new `build_response()` function.
For all responses we need to return from `build_response()`, make new
structs `HtmlResponse` and `ZipResponse` that write the response in the
desired format.
The `ZipResponse` does what we're already doing in `/license/download`.
The `HtmlResponse` will respond with HTML and show a thank-you page on
success.
|
|
The script name isn't necessarily the same as the request path. We
really want the request path.
|
|
|
|
|
|
|
|
Respond with a 500 on error.
Add 'aquatic-prime' to `foreign_links` errors to be able to convert it
with `into()`.
|
|
Read https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing
recently, and reducing the pool size seemed like a good idea.
|
|
|
|
Will make it a bit easier to handle errors from `Result`s.
|
|
|
|
|
|
Forgot that `include_str!` existed. Certainly makes things a lot cleaner
this way.
|
|
If the purchaser coming from POST params is found in the database,
generate a license for the purchaser, zip the license, and send a
response containing the zipped data.
zip:
Change the writer input to a mutable reference to enable us to use the
zip data when writing to the response. Otherwise we get a borrow error.
|
|
Use POST params `name`, `email`, and `secret` to get a purchaser from
the database.
If none exists, we should probably send a 404, otherwise we'll generate
a license for that purchaser and send it in the response as a Zip
archive.
|
|
This binary will show a thank-you page to purchasers. I had also planned
to make a third binary to send the license file as a Zip archive, but
now I think I'm going to do that here too, working out the routing
inside this program.
|
|
This will enable us to use the logging code in other binaries.
|
|
|
|
|
|
Binary to generate a license plist.
|
|
Want a `license-generator` binary with a hyphen. Normally I'd name my
Rust files with underscores, but I didn't want to add `[[bin]]` sections
to `Cargo.toml`.
|
|
Want to make another binary to generate license files.
|
|
Like what I did in edf6fceedd9b4169ceb63172c60733ef84d78951 for 500
errors, extract these errors to functions also.
Doesn't give us any gains in terms of reusability like it did before, as
we're only responding with each of these errors once, but it does clean
up the code in the `main()` function a bit.
|
|
Clean up the `main()` function by extracting all these similar lines to
a function.
|
|
Otherwise we get a borrow error:
error[E0373]: closure may outlive the current function, but it borrows `pool`, which is owned by the current function
--> src/main.rs:67:18
|
67 | fastcgi::run(|mut req| {
| ^^^^^^^^^ may outlive borrowed value `pool`
...
123 | let mut cx = match pool.get_conn() {
| ---- `pool` is borrowed here
help: to force the closure to take ownership of `pool` (and any other referenced variables), use the `move` keyword
|
67 | fastcgi::run(move |mut req| {
| ^^^^^^^^^^^^^^
|
|
This way we can ask the pool for a connection on each request instead of
trying to reuse a single connection.
|
|
This currently errors on a borrow problem with the `cx` in the closure.
Here we get the purchaser name and email from the POST params and insert
them as a record in the database.
If all goes well, we respond with a 200. Otherwise we log errors and
respond with 500.
|
|
Move the call to `params::parse()` from `request::verified()` into
`main()`. This enables us to access values from POST params inside the
`main()` function. We'll need this to store purchaser name and email
address.
|
|
|
|
Log incomming requests to the program's log file.
Remove the 500 error when failing to read stdin to a string. I think it
should be safe to ignore that error. Now that I think about it, we
should be logging it though.
|
|
Previously we were responding with a 200 if all else checked out. This
seems too permissive. Only the authorised webhook requester should
receive a 200. All other requesters should be denied access. Swap the
last two responses to reflect this.
|
|
* If no `REQUEST_METHOD` is found, send a 500 error
* If the `REQUEST_METHOD` is not "POST", send a 405
* If POST params could not be read from stdin, send 500
* If an error occurred during request verification, send 500
* If the request didn't pass verification, send 403
* Otherwise send 200
|
|
Make it easier on users by not requiring them to pass a signature into
the method. This means they don't have to extract the `p_signature`
param and base64 decode it themselves.
Essentially, we want to move the code from `request` that removes the
`p_signature` key and base64 decodes it into the
`paddle::verify_signature()` function.
We need to make the string-like type params in `verify_signature()`
conform additionally to `PartialEq<str>` and `PartialOrd`. Doing so
allows us to find the key "p_signature".
To remove the `p_signature` param from the iterator, we partition it
into two iterators: one for the `p_signature` entry, and another for the
rest. We then extract the value of `p_signature` and base64 decode it
for verification.
Add a new error type in case no `p_signature` entry is found in the
iterator.
|