# # Phishing Detection # # 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. return [from, reply_to] if reply_to isnt from 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)