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

feat(auth): allow non-interactive grants for incoming payments #588

Merged
merged 16 commits into from
Sep 27, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions packages/auth/migrations/20220504161932_create_grants_table.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ exports.up = function (knex) {
table.string('state').notNullable()
table.specificType('startMethod', 'text[]').notNullable()

table.string('continueToken').unique()
table.string('continueId').unique()
table.string('continueToken').notNullable().unique()
table.string('continueId').notNullable().unique()
Copy link
Contributor

@njlie njlie Sep 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldn't be necessary to generate continuation information if interaction (or further continuation) isn't necessary for a grant. The POST / should just return the access token without any continuation information. Continuation information could just be generated if the grant is modified in a way that requires interaction to be issued again (if we end up supporting that again).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we discussed that while you were away. We always want to be able to delete/revoke the grant and for that you need the continue token and id. Hence, it must always be present. We also already changed the spec to make it always required.

table.integer('wait')

table.string('finishMethod').notNullable()
table.string('finishUri').notNullable()
table.string('clientNonce').notNullable()
table.string('finishMethod')
table.string('finishUri')
table.string('clientNonce')
table.string('clientKeyId').notNullable()

table.string('interactId').notNullable().unique()
table.string('interactRef').notNullable().unique()
table.string('interactNonce').notNullable().unique()
table.string('interactId').unique()
table.string('interactRef').unique()
table.string('interactNonce').unique()

table.timestamp('createdAt').defaultTo(knex.fn.now())
table.timestamp('updatedAt').defaultTo(knex.fn.now())
Expand Down
4 changes: 2 additions & 2 deletions packages/auth/src/access/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ interface BaseAccessRequest {
interval?: string
}

interface IncomingPaymentRequest extends BaseAccessRequest {
export interface IncomingPaymentRequest extends BaseAccessRequest {
type: AccessType.IncomingPayment
limits?: never
}
Expand Down Expand Up @@ -58,7 +58,7 @@ export function isAction(actions: Action[]): actions is Action[] {
return true
}

function isIncomingPaymentAccessRequest(
export function isIncomingPaymentAccessRequest(
accessRequest: IncomingPaymentRequest
): accessRequest is IncomingPaymentRequest {
return (
Expand Down
11 changes: 6 additions & 5 deletions packages/auth/src/accessToken/service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,21 +207,21 @@ describe('Access Token Service', (): void => {
await token.$query(trx).patch({ expiresIn: 1000000 })
const result = await accessTokenService.revoke(token.managementId)
expect(result).toBeUndefined()
token = await AccessToken.query(trx).findById(token.id)
token = (await AccessToken.query(trx).findById(token.id)) as AccessToken
sabineschaller marked this conversation as resolved.
Show resolved Hide resolved
expect(token).toBeUndefined()
sabineschaller marked this conversation as resolved.
Show resolved Hide resolved
})
test('Can revoke even if token has already expired', async (): Promise<void> => {
await token.$query(trx).patch({ expiresIn: -1 })
const result = await accessTokenService.revoke(token.managementId)
expect(result).toBeUndefined()
token = await AccessToken.query(trx).findById(token.id)
token = (await AccessToken.query(trx).findById(token.id)) as AccessToken
expect(token).toBeUndefined()
})
test('Can revoke even if token has already been revoked', async (): Promise<void> => {
await token.$query(trx).delete()
const result = await accessTokenService.revoke(token.id)
expect(result).toBeUndefined()
token = await AccessToken.query(trx).findById(token.id)
token = (await AccessToken.query(trx).findById(token.id)) as AccessToken
expect(token).toBeUndefined()
sabineschaller marked this conversation as resolved.
Show resolved Hide resolved
})
})
Expand All @@ -234,6 +234,7 @@ describe('Access Token Service', (): void => {
grant = await Grant.query(trx).insertAndFetch({
...BASE_GRANT,
continueToken: crypto.randomBytes(8).toString('hex').toUpperCase(),
continueId: v4(),
interactId: v4(),
interactRef: crypto.randomBytes(8).toString('hex').toUpperCase(),
interactNonce: crypto.randomBytes(8).toString('hex').toUpperCase()
Expand Down Expand Up @@ -261,9 +262,9 @@ describe('Access Token Service', (): void => {
await token.$query(trx).patch({ expiresIn: -1 })
const result = await accessTokenService.rotate(token.managementId)
expect(result.success).toBe(true)
token = await AccessToken.query(trx).findOne({
token = (await AccessToken.query(trx).findOne({
managementId: result.success && result.managementId
})
})) as AccessToken
sabineschaller marked this conversation as resolved.
Show resolved Hide resolved
expect(token.value).not.toBe(originalTokenValue)
})
test('Cannot rotate nonexistent token', async (): Promise<void> => {
Expand Down
4 changes: 3 additions & 1 deletion packages/auth/src/config/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,7 @@ export const Config = {
accessTokenExpirySeconds: envInt('ACCESS_TOKEN_EXPIRY_SECONDS', 10 * 60), // Default 10 minutes
databaseCleanupWorkers: envInt('DATABASE_CLEANUP_WORKERS', 1),
accessTokenDeletionDays: envInt('ACCESS_TOKEN_DELETION_DAYS', 30),
introspectionHttpsig: process.env.INTROSPECTION_HTTPSIG === 'true'
introspectionHttpsig: process.env.INTROSPECTION_HTTPSIG === 'true',
sabineschaller marked this conversation as resolved.
Show resolved Hide resolved
incomingPaymentInteraction:
process.env.INCOMING_PAYMENT_INTERACTION === 'true'
}
12 changes: 6 additions & 6 deletions packages/auth/src/grant/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ export class Grant extends BaseModel {
public continueId!: string
public wait?: number

public finishMethod!: FinishMethod
public finishUri!: string
public clientNonce!: string // client-generated nonce for post-interaction hash
public finishMethod?: FinishMethod
public finishUri?: string
public clientNonce?: string // client-generated nonce for post-interaction hash
public clientKeyId!: string

public interactId!: string
public interactRef!: string
public interactNonce!: string // AS-generated nonce for post-interaction hash
public interactId?: string
public interactRef?: string
public interactNonce?: string // AS-generated nonce for post-interaction hash
}
Loading