Hi again super heroes! Having a bit of trouble wo...
# sst
r
Hi again super heroes! Having a bit of trouble working out how to get the cognito user pool oauth redirect URLs from the frontend, when the cognito user pool itself is passed into the frontend (so it knows where to redirect users). Bit of a chicken and egg scenario. I'm using the Cognito hosted UI eg. (A few bits missing here, but it explains the core pieces)
Copy code
// cognito stack
        const userPoolClient = userPool.addClient('app-client', {
            oAuth: {
                callbackUrls: [frontendStack.url], // Can't inject this here because the static site isn't made yet
                logoutUrls: [frontendStack.url],
            }
        });

        const userPoolInstance = new sst.Auth(this, "Auth", {
            cognito: {
                userPool,
                userPoolClient,
            },
        });
Copy code
// frontend stack
        const frontendSite = new sst.StaticSite(this, "frontend", {
           environment: {
              "COGNITO_LOGIN": cognitoStack.url  // Need this in the constructor
           }
        }
I have to set those properties in the constructors. There isn't any way to add them afterwards as far as I can see. Surely there is a way to get this working? I can manually construct the user pool domain and pass that around rather than the pool itself, but I kind of like everything being auto-generated so I know it's always correct. But would that be the best solution? Maybe I could defer the creation of the Auth construct until the front-end is made, but then the backend stack (which depends on it) will come after the front-end... And I'm sure that is going to cause issues? It feels like I should be able to set those redirect URLs (callback URLs) after the front-end, but I can't see how.
t
Not sure this is the best answer but could you update the callbackUrl’s with the correct values using the aws-sdk once the StaticSite has deployed
r
I could with a custom resource. I thought it would be a fairly common use case though.
t
I think normally people would use a custom domain name so it would not be an issue
t
Yeah the only way I can think to solve this is to know the domain ahead of time
Our StaticSite construct can't lazy add the environment because it effects the build
r
Thanks, guys. Sounds like it's the way to go! Simpler than a custom resource. We use a custom domain for production, but for dev builds it's quicker and easier to just use the provided domains from AWS.
Hmm.. actually, it's still difficult... It means the frontend gets deployed first, then the auth stack, then the backend... feels really backwards. So the backend becomes dependent on the frontend? Arg... Would something like this work? It looks like it still needs the values on creation though and it can't be lazily added later... https://github.com/aws/aws-cdk/issues/3037#issuecomment-535516097 Think I'll do a custom resource... At least they are super simple with SST 🙂
I implemented a custom resource. It works well. But then next deployment, cloud formation overwrites the user pool with the blank configuration. Is there a way to prevent that from happening? There doesn't seem to be a way to tell it to ignore those fields :(
t
I guess the custom resource would need to check to see if the user pool client is already deployed and get the callback url’s then add those to the user pool client.
r
The custom resource is fine and it adds the callback URLs. It fetches the existing pool client, alters the callback URLs, then updates. There is only a single update API for the whole thing, so that seems to be the only way to do it. The problem is that next deploy the original pool as defined in cloud formation resets the pool back to how it was :(
All I can think of is some trickery to do a lookup, get the existing callbackURLs, then put that into the user pool client creation. That way what is in cloudformation will match...
t
Yup thats what I meant, whats stopping you from adding a domain though? That is definitely the recommended way
r
Thought it would be simpler than setting up domains for dev environments.
When you import an existing
UserPoolClient
, you get an
IUserPoolClient
. The
sst.Auth
construct only accepts
UserPoolClient
. Is there any reason why the
sst.Auth
construct can't work with
IUserPoolClient
? Then I could basically create the user pool client in a script and import it.
Anyway, I set up a domain and changed everything to run off subdomains generated using the stage name. I still prefer being able to just spin up a stack on an AWS account without having to have domains configured on there.