2015-10-03 06:38:48 +08:00
|
|
|
# # 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.
|
2016-01-08 06:56:34 +08:00
|
|
|
return [from, reply_to] if reply_to isnt from
|
2015-10-03 06:38:48 +08:00
|
|
|
|
2016-01-08 06:56:34 +08:00
|
|
|
return [null, null]
|
2015-10-03 06:38:48 +08:00
|
|
|
|
|
|
|
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)
|