Skip to content

Instantly share code, notes, and snippets.

@MatteoGauthier
Created September 30, 2024 08:30
Show Gist options
  • Save MatteoGauthier/82ee0cdf00a861f6658b7d1ba51ef707 to your computer and use it in GitHub Desktop.
Save MatteoGauthier/82ee0cdf00a861f6658b7d1ba51ef707 to your computer and use it in GitHub Desktop.
TypeScript script to manually update logto configuration using the Management API (https://docs.logto.io/docs/recipes/interact-with-management-api/)
const LOGTO_APP_ID = process.env.LOGTO_MANAGEMENT_API_ID
const LOGTO_APP_SECRET = process.env.LOGTO_MANAGEMENT_API_SECRET
const LOGTO_API_RESOURCE = `https://${process.env.LOGTO_TENANT_ID}.logto.app/api`
const LOGTO_APP_ID_TO_UPDATE = process.env.LOGTO_CLIENT_ID
if (!LOGTO_API_RESOURCE || !LOGTO_APP_ID_TO_UPDATE || !LOGTO_APP_ID || !LOGTO_APP_SECRET) {
console.error("Missing environment variables")
process.exit(1)
}
console.log({
LOGTO_APP_ID_TO_UPDATE,
LOGTO_APP_ID,
LOGTO_APP_SECRET,
LOGTO_API_RESOURCE,
})
// Get access token
async function getAccessToken(): Promise<string> {
const tokenEndpoint = `https://${process.env.LOGTO_TENANT_ID}.logto.app/oidc/token`
const auth = Buffer.from(`${LOGTO_APP_ID}:${LOGTO_APP_SECRET}`).toString("base64")
const response = await fetch(tokenEndpoint, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Authorization: `Basic ${auth}`,
},
body: new URLSearchParams({
grant_type: "client_credentials",
resource: `https://${process.env.LOGTO_TENANT_ID}.logto.app/api`,
scope: "all",
}).toString(),
})
const data = await response.json()
return data.access_token
}
const defaultRedirectUris = ["https://example.com/api/logto/sign-in-callback"]
const defaultPostLogoutRedirectUris = ["https://example.com/api/logto/sign-out-redirect"]
async function updateLogtoApplication(accessToken: string, redirectUris: string[], postLogoutRedirectUris: string[]) {
const updateEndpoint = `${LOGTO_API_RESOURCE}/applications/${LOGTO_APP_ID_TO_UPDATE}`
const response = await fetch(updateEndpoint, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify({
oidcClientMetadata: {
redirectUris: redirectUris,
postLogoutRedirectUris: postLogoutRedirectUris,
},
}),
})
if (!response.ok) {
console.log(await response.text())
throw new Error(`Failed to update Logto application: ${response.statusText}`)
}
const data = await response.json()
console.log("Logto application updated successfully:", data)
}
async function main() {
try {
// Prepare redirect URIs and post-logout redirect URIs
const redirectUris = [
...defaultRedirectUris,
]
const postLogoutRedirectUris = [
...defaultPostLogoutRedirectUris,
]
// Get access token
const accessToken = await getAccessToken()
// Update Logto application
await updateLogtoApplication(accessToken, redirectUris, postLogoutRedirectUris)
console.log("Logto application updated successfully with new URIs")
} catch (error) {
console.error("Error updating Logto application:", error)
} finally {
process.exit(0)
}
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error("Unhandled error:", error)
process.exit(1)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment