Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
4 changes: 3 additions & 1 deletion common/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@ server start.
## Errors

```js
const { AuthError, InputError } = require('@kansa/common/errors')
const { AuthError, InputError, NotFoundError } = require('@kansa/common/errors')
```

### `new AuthError(message: string)`

### `new InputError(message: string)`

### `new NotFoundError(message: string)`

Handled by the server's error handling. May also have their `status` set.

## Log entries
Expand Down
10 changes: 9 additions & 1 deletion common/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,12 @@ function InputError(message = 'Input error') {
}
InputError.prototype = new Error()

module.exports = { AuthError, InputError }
function NotFoundError(message = 'Not Found') {
this.name = 'NotFoundError'
this.message = message
this.status = 404
this.stack = new Error().stack
}
NotFoundError.prototype = new Error()

module.exports = { AuthError, InputError, NotFoundError }
1 change: 1 addition & 0 deletions config/database/dev-people.sql
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ ALTER SEQUENCE member_number_seq RESTART WITH 42;
CREATE FUNCTION reset_test_users() RETURNS void AS $$
BEGIN
UPDATE keys SET key='key', expires=NULL WHERE email='admin@example.com';
UPDATE keys SET key='key', expires=NULL WHERE email='site-select@example.com';
UPDATE keys SET key='key', expires='2017-08-13' WHERE email='expired@example.com';
END;
$$ LANGUAGE plpgsql;
11 changes: 11 additions & 0 deletions config/kansa.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ modules:
# Superadmin actions: get & set admin levels, mass sync actions
admin: true

# Badge previews and print logging. Uses tarra, the badge-printer, which in
# turn will need to have the proper fonts included.
badge: false

# Barcodes to help speed up registration. Uses tarra, the badge-printer, which
# in turn will need to have the proper fonts included.
barcode: false

# Nomination and voting for the Hugo Awards
hugo: true

Expand All @@ -54,6 +62,9 @@ modules:
# Art show management
raami: false

# Site selection token management
siteselect: true

# Invite generator for a Slack organisation
slack:
#org: worldcon75
Expand Down
24 changes: 13 additions & 11 deletions config/siteselection/ballot-data.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
function ballotData({
member_number,
legal_name,
email,
city,
state,
country,
badge_name,
paper_pubs,
function ballotData(
{
member_number,
legal_name,
email,
city,
state,
country,
badge_name,
paper_pubs
},
token
}) {
) {
const address = (paper_pubs && paper_pubs.address.split(/[\n\r]+/)) || ['']
return {
info: {
Expand All @@ -24,7 +26,7 @@ function ballotData({
City: city || '',
Country: paper_pubs ? paper_pubs.country : country || '',
'Membership number': member_number || '........',
'Voting token': token,
'Voting token': token || '',
'E-mail': email,
'State/Province/Prefecture': state || '',
'Badge name': badge_name || '',
Expand Down
60 changes: 12 additions & 48 deletions integration-tests/test/badge.spec.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
const assert = require('assert')
const fs = require('fs')
const request = require('supertest')
//const YAML = require('yaml').default
const YAML = require('yaml').default

const config = YAML.parse(fs.readFileSync('../config/kansa.yaml', 'utf8'))
if (!config.modules.badge) return

//const config = YAML.parse(fs.readFileSync('../config/kansa.yaml', 'utf8'))
const ca = fs.readFileSync('../proxy/ssl/localhost.cert', 'utf8')
const host = 'localhost:4430'

let pdfType = 'application/pdf'
let pngType = 'image/png'

if (process.env.CI) {
// Tarra requires fonts that are normally mounted from the file system, and
// are not included in the build on the CI servers. So we hack around the
// problem for now by expecting the responses to fail. -- Eemeli, 2018-09-09
pdfType = 'text/html; charset=UTF-8'
pngType = 'text/html; charset=UTF-8'
}

describe('Badges & barcodes', () => {
describe('Badges', () => {
const key = 'key'
let id = null

Expand All @@ -41,28 +41,16 @@ describe('Badges & barcodes', () => {

it('get own badge', () =>
member
.get(`/api/people/${id}/badge`)
.get(`/api/badge/${id}`)
.expect(200)
.expect('Content-Type', pngType))

it("fail to get other's badge", () =>
member.get(`/api/people/${id - 1}/badge`).expect(401))

it('get own barcode with id as PNG', () =>
member
.get(`/api/people/${id}/barcode.png`)
.expect(200)
.expect('Content-Type', pngType))

it('get own barcode with id as PDF', () =>
member
.get(`/api/people/${id}/barcode.pdf`)
.expect(200)
.expect('Content-Type', pdfType))
member.get(`/api/badge/${id - 1}`).expect(401))

it('fail to log own badge as printed', () =>
member
.post(`/api/people/${id}/print`)
.post(`/api/badge/${id}/print`)
.send()
.expect(401))
})
Expand All @@ -72,24 +60,12 @@ describe('Badges & barcodes', () => {

it('get blank badge', () =>
anonymous
.get('/api/blank-badge')
.get('/api/badge/blank')
.expect(200)
.expect('Content-Type', pngType))

it("fail to get member's badge", () =>
anonymous.get(`/api/people/${id}/badge`).expect(401))

it("get member's barcode with key as PNG", () =>
anonymous
.get(`/api/barcode/${key}/${id}.png`)
.expect(200)
.expect('Content-Type', pngType))

it("get member's barcode with key as PDF", () =>
anonymous
.get(`/api/barcode/${key}/${id}.pdf`)
.expect(200)
.expect('Content-Type', pdfType))
anonymous.get(`/api/badge/${id}`).expect(401))
})

describe('admin access', () => {
Expand All @@ -109,25 +85,13 @@ describe('Badges & barcodes', () => {

it("get member's badge", () =>
admin
.get(`/api/people/${id}/badge`)
.get(`/api/badge/${id}`)
.expect(200)
.expect('Content-Type', pngType))

it("get member's barcode with id as PNG", () =>
admin
.get(`/api/people/${id}/barcode.png`)
.expect(200)
.expect('Content-Type', pngType))

it("get member's barcode with id as PDF", () =>
admin
.get(`/api/people/${id}/barcode.pdf`)
.expect(200)
.expect('Content-Type', pdfType))

it("log the member's badge as printed", () =>
admin
.post(`/api/people/${id}/print`)
.post(`/api/badge/${id}/print`)
.send()
.expect(200)
.expect(res => assert.equal(res.body.status, 'success')))
Expand Down
109 changes: 109 additions & 0 deletions integration-tests/test/barcode.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
const assert = require('assert')
const fs = require('fs')
const request = require('supertest')
const YAML = require('yaml').default

const config = YAML.parse(fs.readFileSync('../config/kansa.yaml', 'utf8'))
if (!config.modules.barcode) return

const ca = fs.readFileSync('../proxy/ssl/localhost.cert', 'utf8')
const host = 'localhost:4430'

let pdfType = 'application/pdf'
let pngType = 'image/png'

if (process.env.CI) {
// Tarra requires fonts that are normally mounted from the file system, and
// are not included in the build on the CI servers. So we hack around the
// problem for now by expecting the responses to fail. -- Eemeli, 2018-09-09
pdfType = 'text/html; charset=UTF-8'
pngType = 'text/html; charset=UTF-8'
}

describe('Barcodes', () => {
const key = 'key'
let id = null

describe('member access', () => {
const member = request.agent(`https://${host}`, { ca })

before(() => {
const email = 'member@example.com'
return member
.get('/api/login')
.query({ email, key })
.expect('set-cookie', /w75/)
.expect(200, { status: 'success', email })
.then(() => member.get('/api/user'))
.then(res => {
id = res.body.people[0].id
assert.equal(typeof id, 'number')
})
})

it('get own barcode with id as PNG', () =>
member
.get(`/api/barcode/${id}.png`)
.expect(200)
.expect('Content-Type', pngType))

it('get own barcode with id as PDF', () =>
member
.get(`/api/barcode/${id}.pdf`)
.expect(200)
.expect('Content-Type', pdfType))

it("fail to get other's barcode", () =>
member.get(`/api/barcode/${id - 1}.png`).expect(401))

it('fail to get own barcode with bad key', () =>
member.get(`/api/barcode/${key + 'x'}/${id}.png`).expect(401))
})

describe('anonymous access', () => {
const anonymous = request.agent(`https://${host}`, { ca })

it("get member's barcode with key as PNG", () =>
anonymous
.get(`/api/barcode/${key}/${id}.png`)
.expect(200)
.expect('Content-Type', pngType))

it("get member's barcode with key as PDF", () =>
anonymous
.get(`/api/barcode/${key}/${id}.pdf`)
.expect(200)
.expect('Content-Type', pdfType))

it('fail to get barcode with bad key', () =>
anonymous.get(`/api/barcode/${key + 'x'}/${id}.png`).expect(401))
})

describe('admin access', () => {
const admin = request.agent(`https://${host}`, { ca })
before(() => {
const email = 'admin@example.com'
return admin
.get('/api/login')
.query({ email, key })
.expect('set-cookie', /w75/)
.expect(200, { status: 'success', email })
.then(() => admin.get('/api/user'))
.then(res => {
assert.notEqual(res.body.roles.indexOf('member_admin'), -1)
})
})

it("get member's barcode with id as PNG", () =>
admin
.get(`/api/barcode/${id}.png`)
.expect(200)
.expect('Content-Type', pngType))

it("get member's barcode with id as PDF", () =>
admin
.get(`/api/barcode/${id}.pdf`)
.expect(200)
.expect('Content-Type', pdfType))
})
})
2 changes: 2 additions & 0 deletions integration-tests/test/hugo-nominations.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const host = 'localhost:4430'
const admin = request.agent(`https://${host}`, { ca })
const nominator = request.agent(`https://${host}`, { ca })

if (!config.modules.hugo) return

const randomString = () => (Math.random().toString(36) + '0000000').slice(2, 7)

describe('Hugo nominations', () => {
Expand Down
Loading