Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot authenticate into Indiekit (hosted on Fly.io) #588

Closed
jayeless opened this issue Feb 13, 2023 · 15 comments
Closed

Cannot authenticate into Indiekit (hosted on Fly.io) #588

jayeless opened this issue Feb 13, 2023 · 15 comments
Assignees
Labels
bug Something isn't working plugin-endpoint Endpoint plug-in

Comments

@jayeless
Copy link

Description of the bug

Hi there, I've been trying to get set up with an install of the latest Indiekit (1.0.0 beta 2), and since Heroku doesn't have a free plan any more, I've been trying to set it up on Fly.io.

I've been able to get Indiekit to run, but I can't authenticate into it. I believe I've set the relevant required environment variables – first SECRET (because Indiekit wouldn't let me create a new password until I'd set that), and then I created a password and used the generated hash to set PASSWORD_SECRET too. I set both of these using Fly's command-line tool. And I can verify that these are both set, using the command-line tool and via the web interface, although I can't inspect the contents of the variables (they're hashed).

My problem is that when I try to log in to Indiekit, and enter the password I'd used, the app just keeps telling me "Enter a valid password". I'm pretty certain the password is correct (I used Bitwarden to generate it and have been copying and pasting) so I feel like something's gone wrong with the environment variables, but I don't know what.

I also tried just sidestepping this problem by setting application.authorizationEndpoint and application.tokenEndpoint to the old IndieAuth URLs, as per the documentation, but Indiekit seems to be ignoring that and just keeps sending me to its own password-based authentication screen. Unless I've misunderstood how providing an alternative authentication/token endpoint is supposed to work and a password is still a prerequisite. Or unless I've set it wrong, because to be fair, I also tried setting a custom application.name and I don't see the name I set that to anywhere. I did follow the format in the example config, copy-pasting the MongoDB URL line and changing the key and value (with quotes around the value strings). Basically that section goes:

  application: {
	authorizationEndpoint: "https://indieauth.com/auth",
	mongodbUrl: process.env.MONGO_URL,
	name: "JLS Indiekit",
	tokenEndpoint: "https://tokens.indieauth.com/token",
  },

While on one level it'd obviously be better to understand why Indiekit's built-in authentication isn't working in the first place, I'd also be happy with a solution that let me revert to the old way of authenticating (which worked in 0.3.0).

Short of "abandoning Fly.io and trying a different host", I'm all out of ideas, but I also don't know why Indiekit wouldn't work on Fly.io. Anyway, apologies for my obvious inexpertise with things like this; I'm very thankful for all the work you've put into Indiekit and would appreciate any help understanding where this is going wrong 🙏

Steps to reproduce

No response

Expected behaviour

No response

Environment

No response

Additional context

No response

@jayeless jayeless added the bug Something isn't working label Feb 13, 2023
@paulrobertlloyd
Copy link
Collaborator

Hi @jayeless. Hmmm, this is a puzzle! I haven’t tried Indiekit with Fly.io yet because, as far as I can tell, it’s all configured using a CLI, is that correct? I have Fly.io in the back of mind for a host to document usage with, but right now you may be an unfortunate guinea pig in trying to use Indiekit with this provider.

Given you are trying to change the application name, and that’s not working either, that might be a good aspect to try and debug first, as there might be something fundamental going on.

Where are you saving your config, and what is the file called?

There are a few different ways to provide configuration to Indiekit, have you tried some of these? I wonder if using the indiekit property in your package.json file might be worth trying. I say this as, if the application is working, then the server must be aware of the presence of this file, at least.

While on one level it'd obviously be better to understand why Indiekit's built-in authentication isn't working in the first place, I'd also be happy with a solution that let me revert to the old way of authenticating (which worked in 0.3.0).

Ideally, you should be able to configure your server to use IndieAuth.com instead of Indiekit’s own authentication feature. But I suspect something more fundamental is going on.

The alternative is to revert back to 0.3.0, but I can understand why that’s not an attractive option either.

@jayeless
Copy link
Author

Thanks @paulrobertlloyd for the response, and the help! And apologies in advance for the long and possibly meandering reply...

To begin: I followed your suggestion to put my configuration directly into package.json, and lo and behold, that worked. My install loaded with the custom title, I was able to authenticate into it via IndieAuth, and I could even successfully submit a post and see it added to my content store (so environmental variables don't seem to be broken). I also got it to recognise the URL I'd given it for my MongoDB database (also via environmental variable). So basically, my problem is almost entirely solved, except that I had a new problem: it doesn't seem like I can customise my post template if my config's all in package.json, and that's pretty important to me. So I did some more digging to try to work out why my config wasn't being picked up where it originally was.

After some experimenting, it became pretty clear that my problem was trying to put my configuration in indiekit.config.js (originally copied from this file in the "example config" repository and then edited with my own details). I'd made a first attempt at getting Indiekit working where I just cloned the example config directory and edited the config file, and that didn't work at all. Then I made a fresh attempt using the setup wizard, and that worked, and then I copy-pasted my edited indiekit.config.js file, and it still seemingly worked but it must've been because Indiekit was just ignoring that (seemingly) malformed config file, and instead looking at the wizard-generated .indiekitrc.json.

I tried re-copying the example config file and changing the absolute bare minimum (like my site URL) and that didn't work either. I didn't try to redeploy to Fly.io, but just testing it on my local computer, I got this error message:

/Users/jess/Documents/GitHub/jls-indiekit/node_modules/cosmiconfig/dist/loaders.js:32
    throw error;
                                                          ^

Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/jess/Documents/GitHub/jls-indiekit/indiekit.config.js from /Users/jess/Documents/GitHub/jls-indiekit/node_modules/cosmiconfig/dist/loaders.js not supported.
indiekit.config.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which declares all .js files in that package scope as ES modules.
Instead rename indiekit.config.js to end in .cjs, change the requiring code to use dynamic import() which is available in all CommonJS modules, or change "type": "module" to "type": "commonjs" in /Users/jess/Documents/GitHub/jls-indiekit/package.json to treat all .js files as CommonJS (using .mjs for all ES modules instead).

    at module.exports (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/import-fresh/index.js:32:59)
    at loadJs (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/cosmiconfig/dist/loaders.js:16:18)
    at ExplorerSync.loadFileContentSync (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/cosmiconfig/dist/ExplorerSync.js:86:14)
    at ExplorerSync.createCosmiconfigResultSync (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/cosmiconfig/dist/ExplorerSync.js:94:30)
    at ExplorerSync.loadSearchPlaceSync (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/cosmiconfig/dist/ExplorerSync.js:70:25)
    at ExplorerSync.searchDirectorySync (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/cosmiconfig/dist/ExplorerSync.js:55:32)
    at run (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/cosmiconfig/dist/ExplorerSync.js:35:27)
    at cacheWrapperSync (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/cosmiconfig/dist/cacheWrapper.js:28:18)
    at ExplorerSync.searchFromDirectorySync (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/cosmiconfig/dist/ExplorerSync.js:47:49)
    at ExplorerSync.searchSync (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/cosmiconfig/dist/ExplorerSync.js:27:25)
    at _getUserConfig (file:///Users/jess/Documents/GitHub/jls-indiekit/node_modules/@indiekit/indiekit/lib/config.js:17:20)
    at getIndiekitConfig (file:///Users/jess/Documents/GitHub/jls-indiekit/node_modules/@indiekit/indiekit/lib/config.js:32:32)
    at new Indiekit (file:///Users/jess/Documents/GitHub/jls-indiekit/node_modules/@indiekit/indiekit/index.js:16:19)
    at Command.<anonymous> (file:///Users/jess/Documents/GitHub/jls-indiekit/node_modules/@indiekit/indiekit/bin/cli.js:27:22)
    at Command.listener [as _actionHandler] (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/commander/lib/command.js:482:17)
    at /Users/jess/Documents/GitHub/jls-indiekit/node_modules/commander/lib/command.js:1283:65
    at Command._chainOrCall (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/commander/lib/command.js:1177:12)
    at Command._parseCommand (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/commander/lib/command.js:1283:27)
    at /Users/jess/Documents/GitHub/jls-indiekit/node_modules/commander/lib/command.js:1081:27
    at Command._chainOrCall (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/commander/lib/command.js:1177:12)
    at Command._dispatchSubcommand (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/commander/lib/command.js:1077:23)
    at Command._parseCommand (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/commander/lib/command.js:1248:19)
    at Command.parse (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/commander/lib/command.js:909:10)
    at file:///Users/jess/Documents/GitHub/jls-indiekit/node_modules/@indiekit/indiekit/bin/cli.js:34:9 {
  code: 'ERR_REQUIRE_ESM',
  filepath: '/Users/jess/Documents/GitHub/jls-indiekit/indiekit.config.js'
}

Node.js v18.14.0

When I followed one of the recommended solutions there and changed the suffix to .cjs, what do you know, Indiekit was able to run, and config settings got picked up from the .cjs file. So then I started re-adding more of my custom config, only to find that it breaks again when I try to re-add my custom post template. Specifically I get this error message:

/Users/jess/Documents/GitHub/jls-indiekit/indiekit.config.cjs:2
import { myPostTemplate } from "./post-template.js";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at internalCompileFunction (node:internal/vm:73:18)
    at wrapSafe (node:internal/modules/cjs/loader:1149:20)
    at Module._compile (node:internal/modules/cjs/loader:1190:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1280:10)
    at Module.load (node:internal/modules/cjs/loader:1089:32)
    at Module._load (node:internal/modules/cjs/loader:930:12)
    at Module.require (node:internal/modules/cjs/loader:1113:19)
    at module.exports (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/import-fresh/index.js:32:59)
    at loadJs (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/cosmiconfig/dist/loaders.js:16:18)
    at ExplorerSync.loadFileContentSync (/Users/jess/Documents/GitHub/jls-indiekit/node_modules/cosmiconfig/dist/ExplorerSync.js:86:14) {
  filepath: '/Users/jess/Documents/GitHub/jls-indiekit/indiekit.config.cjs'
}

Node.js v18.14.0

I did some web searches of the error messages, and basically, what I'm gathering is that there are two types of Javascript files, and one can use require but not import, and the other can use import but not require. At this point I'm kinda hitting the limits of my ability. I tried rewriting the line that imports ./post-template.js to:

const postTemplate = require("./post-template.js");

but then it required me to rename post-template.js to use the .cjs suffix too. And then it didn't like that post-template.cjs used export... so I tried going the other way, and making my config file a .js file where both lines used import, but that gives me error messages too:

Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/jess/Documents/GitHub/jls-indiekit/indiekit.config.js from /Users/jess/Documents/GitHub/jls-indiekit/node_modules/cosmiconfig/dist/loaders.js not supported.
Instead change the require of indiekit.config.js in /Users/jess/Documents/GitHub/jls-indiekit/node_modules/cosmiconfig/dist/loaders.js to a dynamic import() which is available in all CommonJS modules.

So, I don't really know what I'm doing at this point anyway, so I figure I should probably leave it for today. Up to here, my conclusion is: don't try to put config in indiekit.config.js, because that won't work. Either package.json or indiekit.config.cjs does work, but a custom post template doesn't seem possible with the former and I don't know how to make it work with the latter. I guess that's a separate issue from the authentication one though, so let me know if I should create a separate GitHub issue for that if I need further help (and I kinda do need further help).

On the topic of authentication though, even though Indiekit seems to be picking up config in either package.json or indiekit.config.cjs and seeing the environmental variables, I tested the in-built authentication again (not relying on IndieAuth) and that's still not working – still giving me the "Enter a valid password" error. I'm fine with using IndieAuth instead, but I thought it was worth noting that that wasn't fixed in the course of my tinkering, just bypassed.

Thank you again for any and all help given! And on a side note, since you asked about Fly.io: yes, deployments through them are configured on the command line.

@shoesandsocks
Copy link

@jayeless I'm using a custom post template in my indiekit.config.cjs file. I think you were almost there, when you said above "And then it didn't like that post-template.cjs used export..."

Can you modify your post-template.cjs similar to this:

function myPostTemplate(properties) {
  ...
}

module.exports = myPostTemplate

That method of exporting the function seems to work for me, for now. (It's related to your observation about import and require being mutually exclusive... the way functions are exported is similarly one-or-the-other.)

@jayeless
Copy link
Author

@shoesandsocks Aha, thank you for this! That was the exact piece I was missing. I've been able to get my custom post template working now 😊

@paulrobertlloyd
Copy link
Collaborator

paulrobertlloyd commented Feb 24, 2023

@shoesandsocks Thanks for your help on this. I suspected this may have been the case, but was unable to reply. It’s so lovely to see Indiekit’s nascent community help each other out ❤️

Unfortunately Cosmiconfig - which is what I’m using to load configuration files - doesn’t support ES modules, causing this confusion. And it looks like Cosmiconfig is now looking for a new maintainer. The rest of the project uses ES modules, but this is the one area there’s this constraint. It might be possible to resolve this by moving to Lilconfig, but this requires some investigation.

@jayeless Back to your original question; are you now able to authenticate?

@paulrobertlloyd paulrobertlloyd added the plugin-endpoint Endpoint plug-in label Feb 24, 2023
@jayeless
Copy link
Author

@paulrobertlloyd Yes, using IndieAuth I'm able to authenticate now. I did give the in-built auth another try (for the sake of completionism) and it didn't work, but I don't mind using IndieAuth. So I'm all sorted now 😊

@aciccarello
Copy link

Looking at the lilconfig README it sounds like it would still require async loading of the config to support ES modules. Cosmic config does have a draft PR to add ESM support to v8 but the PR is 2+ years old and like you mentioned, that project is looking for a new maintainer. Regardless, it looks like ESM support would require changing indiekit to load the config async.

@aciccarello
Copy link

Actually, it looks like someone has taken over the maintainer role on Cosmicconfig 🎉

@paulrobertlloyd
Copy link
Collaborator

Oh yeah! Sorta resigned myself to the non-maintained status, so didn’t actually check. Hopefully ESM support lands soon – will make things much simpler 🤞

@aciccarello
Copy link

I'm also having trouble getting authentication working with fly.io even with the PASSWORD_SECRET and SECRET set. I was able to get thins working with the indieauth.com endpoint config.

image

@aciccarello
Copy link

aciccarello commented May 14, 2023

I eventually figured this out. I think it might have been related to fly.io's CLI and shell commands. Wrapping the string values in single quotes seemed to work.

@paulrobertlloyd
Copy link
Collaborator

paulrobertlloyd commented May 14, 2023

I eventually figured this out. I think it might have been related to fly.io's CLI and shell commands. Wrapping the string values in single quotes seemed to work.

That’s good to know, thanks for sharing the tip. I’ve been spending this weekend trying to understand Docker and create a config that can be used; having this will probably help in a lot of these cases given services like Fly, Render, Railway etc can use Dockerfiles.

@benborges
Copy link

benborges commented Jun 20, 2023

I'm also having trouble getting authentication working with fly.io even with the PASSWORD_SECRET and SECRET set. I was able to get thins working with the indieauth.com endpoint config.

image

I'm at this step, but locally, can't authenticate with the password I have set in my .env file, i'm probably doing something wrong, but it's not clear, any hint ?

edit : managed to get it working !

  1. had to generate a proper string for the SECRET in my .env
  2. before IndieAuth into the localhost dev site, go to /auth/new-password
  3. paste the generated string into PASSWORD_SECRET in my .env
  4. then IndieAuth works just fine

@paulrobertlloyd
Copy link
Collaborator

paulrobertlloyd commented Jul 28, 2023

Closing this in favour of #540 which tracks the creation of a tutorial for hosting Indiekit on Fly.io.

The initial issue surrounding the configuration file format has also been addressed, with v1.0.0 Beta 4 adding support for configuration files that use either the CommonJS or ES module syntaxes.

@benborges
Copy link

Sorry haven't had the time, but i will try again with these fixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working plugin-endpoint Endpoint plug-in
Projects
None yet
Development

No branches or pull requests

5 participants