Security News
pnpm 10.0.0 Blocks Lifecycle Scripts by Default
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
atlassian-connect-auth
Advanced tools
This library implements authentication for installation requests, webhooks, and page loading from Atlassian products built with Connect.
For a deeper understanding of the concepts built into this library, please read through the Atlassian Connect documentation for the corresponding product:
import {
AuthError,
AuthErrorCode,
CredentialsWithEntity,
ExpressReqAuthDataProvider,
InstallationType,
verifyInstallation,
verifyRequest,
} from 'atlassian-connect-auth'
// Consumers of this library have to provide a KeyProvider implementation that will fetch the public key from a CDN.
// Examples can be found under the `test` directory in this library.
import { GotKeyProvider } from './GotKeyProvider';
const baseUrl = 'https://your-app-base-url.com'
const asymmetricKeyProvider = new GotKeyProvider()
async function loadInstallationEntity(clientKey: string): Promise<CredentialsWithEntity<InstallationEntity>> {
const storedEntity = await model.InstallationEntity.findOne({ where: { clientKey } })
if (storedEntity) {
return {
sharedSecret: decrypt(storedEntity.encryptedSharedSecret),
storedEntity,
}
}
}
const handleInstallation = async (req, res) => {
try {
const result = await verifyInstallation({
baseUrl,
asymmetricKeyProvider,
authDataProvider: new ExpressReqAuthDataProvider(req),
credentialsLoader: loadInstallationEntity,
})
const newInstallationEntity = req.body
if (result.type === InstallationType.update) {
const existingInstallationEntity = result.storedEntity
await existingInstallationEntity.update(newInstallationEntity)
} else {
await model.InstallationEntity.create(newInstallationEntity)
}
res.sendStatus(201)
} catch (error) {
if (error instanceof AuthError) {
console.warn(error)
res.sendStatus(401)
} else {
console.error(error)
res.sendStatus(500)
}
}
}
const handleAuth = async (req, res, next) => {
try {
const { connectJwt, storedEntity } = await verifyRequest({
baseUrl,
asymmetricKeyProvider,
authDataProvider: new ExpressReqAuthDataProvider(req),
credentialsLoader: loadInstallationEntity,
queryStringHashType: 'context',
})
req.context = {
accountId: connectJwt.context?.user?.accountId ?? connectJwt.sub,
installationData: storedEntity
}
next()
} catch (error) {
if (error instanceof AuthError) {
console.warn(error)
res.sendStatus(401)
} else {
console.error(error)
res.sendStatus(500)
}
}
}
const app = express()
.post('/api/hooks/jira/installed', handleInstall)
.post('/api/hooks/jira/uninstalled', handleAuth, handleUninstall)
.post('/api/hooks/jira/project/created', handleAuth, handleProjectCreated)
3.x
with signed installsAddon
class was replaced with stateless function callsRemove class instantiation and replace method calls with function calls as follows:
addon.auth()
⟶ verifyRequest()
addon.install()
⟶ verifyInstallation()
Also:
baseUrl
argument from the class instantiation to the function calls.product
argument altogether.loadCredentials
with credentialsLoader
.
sharedSecret
property.sharedSecret
property and optionally your
stored database value instoredEntity
as follows:
return {
sharedSecret: '...',
storedEntity: databaseInstallationData,
}
saveCredentials
from the installation verification. Use the request body payload to persist the installation data. It's safe after verifying the installation request.storedEntity
will be returned by the verification function if a value is provided.
verifyInstallation()
will return
the loaded entity with an attribute also named storedEntity
.verifyInstallation()
will not
return the property storedEntity
.Replace the argument skipQsh
with queryStringHashType
, which is an enum with
the following values:
'skip'
: skip QSH verification altogether. Use this in routes you had skipQsg: true
.'computed'
: force verification using regular QSH algorithm.'context'
: force verification using static value context-qsh
.'any'
: accepts both 'computed'
and 'context'
.Note: Bitbucket Cloud does not currently support context-qsh
as it does not have a JavaScript API that
allows generating a context token.
Version 2.x
took a request object as the first argument of the verifications functions. It expected
an Express.js-like request object in order to extract the token from headers or query arguments.
Version 3.x
decouples that from the web framework with the authDataProvider
parameter.
authDataProvider
.
ExpressReqAuthDataProvider
. Example:
verifyRequest({
authDataProvider: new ExpressReqAuthDataProvider(req),
...
})
customExtractToken
with your implementation of AuthDataProvider
.
AuthDataProvider
with your own token extraction.ExpressReqAuthDataProvider
and add new ways of extracting the token from the req
object.
For instance: export class MyAuthDataProvider extends ExpressReqAuthDataProvider {
extractConnectJwt(): string {
// Custom query argument
const jwt = this.req.query.customJwt as string
if (jwt) {
return jwt
}
// fallback to regular Connect token extraction
return super.extractConnectJwt()
}
}
Add the authorizationMethod
argument to the verification methods to define how
you want installations to be verified.
sharedSecret
: force legacy method that won't check new installations and will use the sharedSecret
to verify
installation updates and uninstallations.publicKey
: force new signed installs that use a public key to verify new installations, installation updates,
and uninstallations.any
: accept both verification methods, meant to be used during the transition period. This is the default value.Note: Bitbucket Cloud does not support signed installs as of 2021. You can still upgrade the library and keep it in compatibility mode (accepting legacy installs) as a preparation for a future upgrade.
Signed installations need to download a public key from the Atlassian Connect CDN. You need to provide an
asymmetricKeyProvider
to the verification functions.
KeyProvider
interface with your HTTP client implementation.ConnectInstallKeysCdnUrl
provides the base URLs for the Atlassian Connect CDN../test/keyProviderExamples
for examples of implementations using Axios, Got, and Node Fetch.AuthErrorCode
enum.'MISSED_TOKEN'
is now AuthErrorCode.MISSING_JWT
'MISSED_QSH'
is now AuthErrorCode.MISSING_QSH
apiMigrations: {
gdpr: true,
'context-qsh': true,
'signed-install': true,
},
atlassian-jwt
to 2.x
, if you have a direct dependency.
atlassian-jwt@2.x
.encode()
with encodeSymmetric()
or encodeAsymmetric()
.decode()
with decodeSymmetric()
or decodeAsymmetric()
. Passing the algorithm is required.FAQs
Helper for handling webhooks from Atlassian products
The npm package atlassian-connect-auth receives a total of 18 weekly downloads. As such, atlassian-connect-auth popularity was classified as not popular.
We found that atlassian-connect-auth demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
Product
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.
Research
Security News
Socket researchers have discovered multiple malicious npm packages targeting Solana private keys, abusing Gmail to exfiltrate the data and drain Solana wallets.