-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
1,472 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import Controller from '@ember/controller'; | ||
|
||
export default class PollController extends Controller { | ||
queryParams = ['k']; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { setupWorker } from 'msw'; | ||
import handlers from './handlers'; | ||
|
||
export const worker = setupWorker(...handlers); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
type EncryptedValue = { | ||
ciphertext: Array<number>; | ||
iv: Array<number>; | ||
}; | ||
|
||
type PollAttributes = { | ||
encryptedDescription: EncryptedValue; | ||
encryptedTitle: EncryptedValue; | ||
salt: Array<number>; | ||
}; | ||
|
||
export class Poll { | ||
id: string; | ||
attributes: PollAttributes; | ||
options: Option[] = []; | ||
|
||
constructor({ id, attributes }: { id: string; attributes: PollAttributes }) { | ||
this.id = id; | ||
this.attributes = attributes; | ||
} | ||
|
||
addOption(data: { id: string; attributes: OptionAttributes }) { | ||
const option = new Option(data); | ||
this.options.push(option); | ||
} | ||
} | ||
|
||
type OptionAttributes = { | ||
encryptedDate: EncryptedValue; | ||
}; | ||
|
||
export class Option { | ||
id: string; | ||
attributes: OptionAttributes; | ||
|
||
constructor({ | ||
id, | ||
attributes, | ||
}: { | ||
id: string; | ||
attributes: OptionAttributes; | ||
}) { | ||
this.id = id; | ||
this.attributes = attributes; | ||
} | ||
} | ||
|
||
export const polls = new Map<string, Poll>(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { rest } from 'msw'; | ||
import { Poll, polls } from './db'; | ||
|
||
export const createPollHandler = rest.post('/polls', async (req, res, ctx) => { | ||
const document = await req.json(); | ||
const poll = new Poll(document['bulk:data'][0]); | ||
|
||
for (const optionResourceObject of document['bulk:included']) { | ||
poll.addOption(optionResourceObject); | ||
} | ||
|
||
polls.set(poll.id, poll); | ||
|
||
return res(ctx.status(204)); | ||
}); | ||
|
||
export const getPollHandler = rest.get('/polls/:pollId', (req, res, ctx) => { | ||
const { pollId } = req.params; | ||
|
||
if (typeof pollId !== 'string') { | ||
throw new Error(`${pollId} is not a valid ID for a poll`); | ||
} | ||
|
||
const poll = polls.get(pollId); | ||
if (!poll) { | ||
return res(ctx.status(404)); | ||
} | ||
|
||
const document = { | ||
data: { | ||
id: poll.id, | ||
type: 'polls', | ||
attributes: poll.attributes, | ||
relationships: { | ||
options: { | ||
data: poll.options.map((option) => { | ||
return { | ||
id: option.id, | ||
type: 'options', | ||
}; | ||
}), | ||
}, | ||
}, | ||
}, | ||
included: [ | ||
poll.options.map((option) => { | ||
return { | ||
id: option.id, | ||
attributes: option.attributes, | ||
}; | ||
}), | ||
], | ||
}; | ||
|
||
return res(ctx.status(200), ctx.json(document), ctx.delay()); | ||
}); | ||
|
||
export default [createPollHandler, getPollHandler]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import Option from './option'; | ||
import Poll from './poll'; | ||
|
||
export { Option, Poll }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
type OptionSignature = { | ||
date: string; | ||
}; | ||
|
||
export default class Option { | ||
readonly id: string = window.crypto.randomUUID(); | ||
readonly date: string; | ||
|
||
constructor({ date }: OptionSignature) { | ||
this.date = date; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import Option from './option'; | ||
import { action } from '@ember/object'; | ||
import { | ||
deriveKey, | ||
encrypt, | ||
randomPassphrase, | ||
randomSalt, | ||
} from 'croodle/utils/crypto'; | ||
|
||
type PollSignature = { | ||
description: string; | ||
options: Option[]; | ||
title: string; | ||
}; | ||
|
||
export default class Poll { | ||
readonly description: string; | ||
readonly id: string = window.crypto.randomUUID(); | ||
readonly options: Option[]; | ||
readonly passphrase: string = randomPassphrase(); | ||
readonly salt: Uint8Array = randomSalt(); | ||
readonly title: string; | ||
|
||
constructor({ description, options, title }: PollSignature) { | ||
this.description = description; | ||
this.options = options; | ||
this.title = title; | ||
} | ||
|
||
@action | ||
async save(): Promise<void> { | ||
const { passphrase, salt } = this; | ||
const key = await deriveKey(passphrase, salt); | ||
|
||
const document = { | ||
'bulk:data': [ | ||
{ | ||
type: 'polls', | ||
id: this.id, | ||
attributes: { | ||
encryptedDescription: await encrypt(this.description, key), | ||
encryptedTitle: await encrypt(this.title, key), | ||
salt: Array.from(this.salt), | ||
}, | ||
}, | ||
], | ||
'bulk:included': await Promise.all( | ||
this.options.map(async (option) => { | ||
return { | ||
type: 'options', | ||
id: option.id, | ||
attributes: { | ||
encryptedDate: await encrypt(option.date, key), | ||
}, | ||
relationships: { | ||
poll: { | ||
data: { | ||
type: 'poll', | ||
id: this.id, | ||
}, | ||
}, | ||
}, | ||
}; | ||
}) | ||
), | ||
}; | ||
|
||
await fetch('/polls', { | ||
body: JSON.stringify(document), | ||
headers: { | ||
'Content-Type': | ||
'application/vnd.api+json; ext="https://github.com/jelhan/json-api-bulk-create-extension"', | ||
}, | ||
method: 'POST', | ||
}); | ||
|
||
return; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import Route from '@ember/routing/route'; | ||
|
||
const SHOULD_MOCK_API = true; | ||
|
||
export default class ApplicationRoute extends Route { | ||
async beforeModel() { | ||
if (SHOULD_MOCK_API) { | ||
const { worker } = await import('../mocks/browser'); | ||
worker.start(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
{{page-title "Croodle"}} | ||
|
||
{{outlet}} | ||
<div class="container"> | ||
{{outlet}} | ||
</div> |
Oops, something went wrong.