Skip to content

Commit

Permalink
Merge pull request #44 from github/csrf-element
Browse files Browse the repository at this point in the history
Support for CSRF token in a child element
  • Loading branch information
koddsson authored Jan 13, 2020
2 parents f3c75bd + 6daf9ce commit fa5c3c8
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,20 @@ import '@github/auto-check-element'
</auto-check>
```

Note that in the following example the CSRF element is marked with the `data-csrf` attribute rather than `name` so that the value doesn't get posted to the backend when the element is placed in a form.

```erb
<auto-check src="/signup-check/username">
<input>
<input hidden data-csrf value="<%= authenticity_token_for("/signup-check/username") %>">
</auto-check>
```

## Attributes

- `src` is the server endpoint that will receive POST requests. The posted form contains a `value` parameter containing the text input to validate. Responding with a 200 OK status indicates the provided value is valid. Any other error status response indicates the provided value is invalid.
- `csrf` is the [CSRF][] token for the posted form. It's available in the request body as a `authenticity_token` form parameter.
- You can also supply the CSRF token via a child element. See [usage](#Usage) example.
- `required` is a boolean attribute that requires the validation to succeed before the surrounding form may be submitted.

## Events
Expand Down
3 changes: 2 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ export default class AutoCheckElement extends HTMLElement {
}

get csrf(): string {
return this.getAttribute('csrf') || ''
const csrfElement = this.querySelector('[data-csrf]')
return this.getAttribute('csrf') || (csrfElement instanceof HTMLInputElement && csrfElement.value) || ''
}

set csrf(value: string) {
Expand Down
29 changes: 29 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,35 @@ describe('auto-check element', function() {
assert.deepEqual(events, [])
})
})

describe('csrf support', function() {
afterEach(function() {
document.body.innerHTML = ''
})

it('fetches CSRF tokens from attributes', function() {
const container = document.createElement('div')
container.innerHTML = `
<auto-check csrf="foo" src="/success" required>
<input>
</auto-check>`
document.body.append(container)
const autoCheck = document.querySelector('auto-check')
assert.equal(autoCheck.csrf, 'foo')
})

it('fetches CSRF tokens from child elements', function() {
const container = document.createElement('div')
container.innerHTML = `
<auto-check src="/success" required>
<input>
<input type="hidden" data-csrf value="foo">
</auto-check>`
document.body.append(container)
const autoCheck = document.querySelector('auto-check')
assert.equal(autoCheck.csrf, 'foo')
})
})
})

function once(element, eventName) {
Expand Down

0 comments on commit fa5c3c8

Please sign in to comment.