suspend fun onUserAuthFlowCompletedInSpace()

in src/main/kotlin/org/jetbrains/slackUnfurls/spaceUnfurlsInSlack/SpaceOAuthFlow.kt [52:124]


suspend fun onUserAuthFlowCompletedInSpace(call: ApplicationCall, params: Routes.SpaceOAuthCallback) {
    if (params.error != null || params.error_description != null) {
        call.respondError(HttpStatusCode.BadRequest, log, "Error while authenticating in Space - ${params.error}, ${params.error_description}")
        return
    }

    if (params.state.isNullOrBlank()) {
        call.respondError(HttpStatusCode.BadRequest, log, "Expected state query string parameter in request")
        return
    }

    if (params.code.isNullOrBlank()) {
        call.respondError(HttpStatusCode.BadRequest, log, "Expected code query string parameter in request")
        return
    }

    val session = db.spaceOAuthSessions.get(params.state)
    if (session == null) {
        call.respondError(
            HttpStatusCode.BadRequest,
            log,
            "Authentication session has expired, try again (flow id = ${params.state})"
        )
        return
    }

    withSlackLogContext(session.slackTeamId, session.slackUserId, session.spaceOrgId) {
        val spaceOrg = db.spaceOrgs.getById(session.spaceOrgId, session.slackTeamId)
        if (spaceOrg == null) {
            call.respondError(HttpStatusCode.BadRequest, log, "Space organization is not connected to Slack workspace")
            return@withSlackLogContext
        }

        val (accessToken, refreshToken) = Space
            .exchangeAuthCodeForToken(
                spaceOAuthHttpClient,
                spaceOrg.toSpaceAppInstance(),
                params.code,
                redirectUri = "$entrypointUrl/space/oauth/callback"
            )
            .let { it.accessToken to it.refreshToken }
        if (accessToken.isBlank() || refreshToken.isNullOrBlank()) {
            call.respondError(HttpStatusCode.Unauthorized, log, "Could not get OAuth refresh token from Space")
            return@withSlackLogContext
        }

        db.spaceUserTokens.save(
            slackTeamId = session.slackTeamId,
            slackUserId = session.slackUserId,
            spaceOrgId = session.spaceOrgId,
            accessToken = encrypt(accessToken),
            refreshToken = encrypt(refreshToken),
            permissionScopes = session.permissionScopes
        )

        processDeferredLinkSharedEvents(
            slackTeamId = session.slackTeamId,
            slackUserId = session.slackUserId,
            spaceOrgId = session.spaceOrgId
        )

        val backUrl = session.backUrl
        if (backUrl != null) {
            log.info("Successfully authenticated user in Space, redirecting to back url")
            call.respondRedirect(backUrl)
        } else {
            call.respondSuccess(
                log,
                "Successfully authenticated with Space. Now Space links in your chat messages in Slack will be accompanied with previews."
            )
        }
    }
}