Skip to content

Commit

Permalink
add optional passphrase (bukinoshita#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
bukinoshita committed Nov 23, 2017
1 parent 143cf33 commit 258efe9
Show file tree
Hide file tree
Showing 3 changed files with 268 additions and 39 deletions.
91 changes: 86 additions & 5 deletions pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ class Home extends Component {

this.onInputChange = this.onInputChange.bind(this)
this.onSubmit = this.onSubmit.bind(this)
this.addPassphrase = this.addPassphrase.bind(this)

this.state = { message: '' }
this.state = { message: '', hasPassphrase: false, passphrase: '' }
}

onInputChange(event) {
Expand All @@ -29,20 +30,97 @@ class Home extends Component {
onSubmit(event) {
event.preventDefault()

const { message } = this.state
const { message, passphrase } = this.state

if (message.length >= 1) {
return api
.post('/secret', { message })
.post('/secret', { message, passphrase })
.then(({ uid }) => {
Router.push(`/secret?uid=${uid}`)
})
.catch(err => console.log(err))
}
}

addPassphrase() {
this.setState({ hasPassphrase: true })
}

render() {
const { message } = this.state
const { message, hasPassphrase, passphrase } = this.state

const passphraseInput = hasPassphrase ? (
<fieldset>
<input
type="text"
placeholder="Your passphrase"
name="passphrase"
value={passphrase}
onChange={this.onInputChange}
autoFocus={true}
/>

<style jsx>{`
fieldset {
border: 0;
}
input {
width: 100%;
resize: none;
background-color: transparent;
border: 1px solid ${colors.gray};
padding: 15px;
font-size: ${typography.f12};
color: ${colors.white};
margin-top: 15px;
outline: none;
font-weight: ${typography.semibold};
transition: all 200ms;
}
input::-webkit-input-placeholder {
color: ${colors.gray};
}
input::-moz-placeholder {
color: ${colors.gray};
}
input:-ms-input-placeholder {
color: ${colors.gray};
}
input:-moz-placeholder {
color: ${colors.gray};
}
input:focus {
border-color: ${colors.white};
}
`}</style>
</fieldset>
) : (
<span onClick={this.addPassphrase}>
+ add passphrase
<style jsx>{`
span {
display: table;
color: ${colors.gray};
text-align: left;
font-size: ${typography.f12};
font-weight: ${typography.semibold};
margin-top: 5px;
cursor: pointer;
transition: all 0.2s;
}
span:hover {
color: ${colors.white};
}
`}</style>
</span>
)

return (
<Page>
Expand All @@ -52,8 +130,11 @@ class Home extends Component {
name="message"
value={message}
onChange={this.onInputChange}
autoFocus={true}
/>

{passphraseInput}

<button type="submit">Create</button>
</form>

Expand All @@ -69,7 +150,7 @@ class Home extends Component {
textarea {
width: 100%;
resize: none;
min-height: 150px;
min-height: 100px;
background-color: transparent;
border: 1px solid ${colors.gray};
padding: 15px;
Expand Down
214 changes: 181 additions & 33 deletions pages/s/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,41 +16,148 @@ class S extends Component {

if (headers.browser.name) {
try {
const { secret } = await api.get(`/secret/${query.id}`)
const data = await api.get(`/secret/${query.id}`)

return { secret, headers }
return { data, headers }
} catch (err) {
return { err }
}
}
}

constructor() {
super()

this.onInputChange = this.onInputChange.bind(this)
this.revealSecret = this.revealSecret.bind(this)

this.state = {
hasPassphrase: false,
passphrase: '',
message: '',
fetched: false,
sFetched: false
}
}

componentDidMount() {
const { data } = this.props
const hasPassphrase = data ? data.hasPassphrase : false

if (data && data.secret && data.secret.message) {
this.setState({ message: data.secret.message })
}

this.setState({ hasPassphrase, fetched: true })
}

onInputChange(event) {
const { target } = event
const { name, value } = target

this.setState({ [name]: value })
}

revealSecret(e) {
e.preventDefault()
const { id } = this.props.url.query
const { passphrase } = this.state

return api
.get(`/secret/${id}?passphrase=${passphrase}`)
.then(res => {
const message = res.secret.message
this.setState({ message, sFetched: true })
})
.catch(() => this.setState({ sFetched: true, passphrase: '' }))
}

render() {
const { secret } = this.props
const { hasPassphrase, passphrase, message, fetched } = this.state

const s = secret ? (
<div>
<label>The secret is</label>
<h1>`{secret.message}`</h1>
const styles = this.state.sFetched ? { borderColor: 'red' } : null

const passphraseInput = hasPassphrase ? (
<div>
<p>Shh... we cannot tell you the secret without the passphrase.</p>
<form onSubmit={this.revealSecret}>
<input
type="text"
placeholder="Your passphrase"
name="passphrase"
value={passphrase}
onChange={this.onInputChange}
style={styles}
autoFocus={true}
/>
<div>
<button type="submit">Reveal the secret</button>
</div>
</form>
<style jsx>{`
label {
color: ${colors.white};
text-transform: uppercase;
display: block;
font-weight: 600;
p {
color: ${colors.gray};
font-size: ${typography.f12};
font-weight: ${typography.semibold};
margin-top: 10px;
}
input {
width: 100%;
resize: none;
background-color: transparent;
border: 1px solid ${colors.gray};
padding: 15px;
font-size: ${typography.f12};
color: ${colors.white};
margin-top: 15px;
outline: none;
font-weight: ${typography.semibold};
transition: all 200ms;
max-width: 500px;
}
h1 {
input::-webkit-input-placeholder {
color: ${colors.gray};
font-style: italic;
font-size: ${typography.f14};
}
input::-moz-placeholder {
color: ${colors.gray};
}
input:-ms-input-placeholder {
color: ${colors.gray};
}
input:-moz-placeholder {
color: ${colors.gray};
}
input:focus {
border-color: ${colors.white};
}
button {
display: inline-block;
background-color: ${colors.white};
color: ${colors.black};
border: 0;
border-radius: 0;
padding: 12px 80px;
font-size: ${typography.f10};
text-transform: uppercase;
font-weight: ${typography.bold};
line-height: 24px;
margin: 30px auto 70px;
transition: all 0.2s;
max-width: 600px;
margin: 30px auto;
text-align: center;
cursor: pointer;
outline: none;
letter-spacing: 2px;
transition: all 200ms;
}
button:focus,
button:hover {
box-shadow: 0 4px 20px rgba(255, 255, 255, 0.5);
}
`}</style>
</div>
Expand All @@ -65,36 +172,48 @@ class S extends Component {
line-height: 24px;
margin: 30px auto 70px;
transition: all 0.2s;
cursor: pointer;
max-width: 600px;
}
`}</style>
</h1>
)

return (
<Page>
<section>
{s}
const showMessage = message ? (
<div>
<label>Your secret is:</label>
<h1>{message}</h1>

<p>
<Link prefetch href="/">
<span>create a secret</span>
</Link>
</p>
</section>
<p>
<Link prefetch href="/">
<span>create a secret</span>
</Link>
</p>

<style jsx>{`
section {
text-align: center;
label {
color: ${colors.white};
text-transform: uppercase;
display: block;
font-weight: 600;
font-size: ${typography.f12};
}
h1 {
color: ${colors.gray};
font-style: italic;
font-size: ${typography.f14};
font-weight: ${typography.bold};
line-height: 24px;
margin: 30px auto 70px;
transition: all 0.2s;
max-width: 600px;
}
span {
border-bottom: 1px solid ${colors.gray};
cursor: pointer;
transition: all 0.2s;
}
span:hover {
color: ${colors.white};
border-color: ${colors.white};
Expand All @@ -106,6 +225,35 @@ class S extends Component {
text-transform: lowercase;
}
`}</style>
</div>
) : (
passphraseInput
)

const m = fetched ? (
showMessage
) : (
<p>
loading...{' '}
<style jsx>{`
p {
color: ${colors.white};
font-size: ${typography.f14};
font-weight: ${typography.semibold};
}
`}</style>
</p>
)

return (
<Page>
<section>{m}</section>

<style jsx>{`
section {
text-align: center;
}
`}</style>
</Page>
)
}
Expand Down
Loading

0 comments on commit 258efe9

Please sign in to comment.