{React,
This is a simple package to notify N1 users if an email is a potential phishing scam.
You can access N1 dependencies by requiring ‘nylas-exports’
{React,
The ComponentRegistry manages all React components in N1.
ComponentRegistry,
A Store
is a Flux component which contains all business logic and data
models to be consumed by React components to render markup.
MessageStore} = require 'nylas-exports'
Notice that this file is main.cjsx
rather than main.coffee
. We use the
.cjsx
filetype because we use the CJSX DSL to describe markup for React to
render. Without the CJSX, we could just name this file main.coffee
instead.
class PhishingIndicator extends React.Component
Adding a @displayName to a React component helps for debugging.
@displayName: 'PhishingIndicator'
@propTypes is an object which validates the datatypes of properties that this React component can receive.
@propTypes:
thread: React.PropTypes.object.isRequired
A React component’s render
method returns a virtual DOM element described
in CJSX. render
is deterministic: with the same input, it will always
render the same output. Here, the input is provided by @isPhishingAttempt.
@state
and @props
are popular inputs as well.
render: =>
Our inputs for the virtual DOM to render come from @isPhishingAttempt.
[from, reply_to] = @isPhishingAttempt()
We add some more application logic to decide how to render.
if from isnt null and reply_to isnt null
React.createElement("div", {"className": "phishingIndicator"},
React.createElement("b", null, "This message looks suspicious!"),
React.createElement("p", null, "It originates from ", (from), " but replies will go to ", (reply_to), ".")
)
If you don’t want a React component to render anything at all, then your
render
method should return null
or undefined
.
else
null
isPhishingAttempt: =>
In this package, the MessageStore is the source of our data which will be
the input for the render
function. @isPhishingAttempt is performing some
domain-specific application logic to prepare the data for render
.
message = MessageStore.items()[0]
This package’s strategy to ascertain whether or not the email is a
phishing attempt boils down to checking the replyTo
attributes on
Message
models from MessageStore
.
if message.replyTo? and message.replyTo.length != 0
The from
and replyTo
attributes on Message
models both refer to
arrays of Contact
models, which in turn have email
attributes.
from = message.from[0].email
reply_to = message.replyTo[0].email
This is our core logic for our whole package! If the from
and
replyTo
emails are different, then we want to show a phishing warning.
if reply_to isnt from
return [from, reply_to]
return [null, null];
module.exports =
Activate is called when the package is loaded. If your package previously
saved state using serialize
it is provided.
activate: (@state) ->
This is a good time to tell the ComponentRegistry
to insert our
React component into the 'MessageListHeaders'
part of the application.
ComponentRegistry.register PhishingIndicator,
role: 'MessageListHeaders'
Serialize is called when your package is about to be unmounted. You can return a state object that will be passed back to your package when it is re-activated.
serialize: ->
This optional method is called when the window is shutting down, or when your package is being updated or disabled. If your package is watching any files, holding external resources, providing commands or subscribing to events, release them here.
deactivate: ->
ComponentRegistry.unregister(PhishingIndicator)