Skip to content

Commit

Permalink
browser extension (#5)
Browse files Browse the repository at this point in the history
* extension support init

* fix check origin
  • Loading branch information
aayushmau5 authored Jun 2, 2024
1 parent eda789a commit 0dc104e
Show file tree
Hide file tree
Showing 11 changed files with 238 additions and 3 deletions.
6 changes: 6 additions & 0 deletions config/dev.exs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ config :accumulator, AccumulatorWeb.Endpoint,
# Binding to loopback ipv4 address prevents access from other machines.
# Change to `ip: {0, 0, 0, 0}` to allow access from other machines.
http: [ip: {0, 0, 0, 0}, port: 4000],
https: [
port: 4001,
cipher_suite: :strong,
certfile: "priv/cert/selfsigned.pem",
keyfile: "priv/cert/selfsigned_key.pem"
],
check_origin: false,
code_reloader: true,
debug_errors: true,
Expand Down
3 changes: 1 addition & 2 deletions config/prod.exs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ config :accumulator, AccumulatorWeb.Endpoint,
check_origin: [
"https://aayushsahu.com",
"https://phoenix-aayushsahu-com.fly.dev",
"https://phoenix.aayushsahu.com/",
"moz-extension://*"
"https://phoenix.aayushsahu.com/"
]

# Do not print debug messages in production
Expand Down
3 changes: 2 additions & 1 deletion lib/accumulator/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ defmodule Accumulator.Application do
Accumulator.Repo,
{Accumulator.Scheduler.Spotify, interval: 60000},
{Accumulator.Scheduler.Pastes, interval: 3_600_000},
{Task.Supervisor, name: Accumulator.TaskRunner}
{Task.Supervisor, name: Accumulator.TaskRunner},
Accumulator.Extension
]

# See https://hexdocs.pm/elixir/Supervisor.html
Expand Down
30 changes: 30 additions & 0 deletions lib/accumulator/extension.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
defmodule Accumulator.Extension do
@moduledoc """
Stuff for browser extension
"""
alias Accumulator.{Repo, Extension.Bookmarks}

# Agent stuff

use Agent

def start_link(_params) do
Agent.start_link(fn -> %{} end, name: __MODULE__)
end

def add_tabs(id, tabs) do
Agent.update(__MODULE__, fn state ->
Map.update(state, id, [], fn _ -> tabs end)
end)
end

def get_tabs(id) do
Agent.get(__MODULE__, & &1) |> Map.delete(id)
end

def add_bookmark(params) do
%Bookmarks{}
|> Bookmarks.changeset(params)
|> Repo.insert()
end
end
19 changes: 19 additions & 0 deletions lib/accumulator/extension/bookmarks.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
defmodule Accumulator.Extension.Bookmarks do
use Ecto.Schema
import Ecto.Changeset

schema "extension_bookmarks" do
field(:url, :string)
field(:title, :string)
field(:browser_id, :string)
timestamps(updated_at: false)
end

def changeset(bookmark, params \\ %{}) do
fields = [:url, :title, :browser_id]

bookmark
|> cast(params, fields)
|> validate_required(fields)
end
end
59 changes: 59 additions & 0 deletions lib/accumulator_web/channels/extension_channel.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
defmodule AccumulatorWeb.ExtensionChannel do
use AccumulatorWeb, :channel

alias Accumulator.Extension
alias AccumulatorWeb.Presence

@impl true
def join("extension", %{"browser" => browser, "id" => id} = _payload, socket) do
send(self(), :after_join)
{:ok, socket |> assign(:browser, browser) |> assign(:id, id)}
end

@impl true
def handle_info(:after_join, socket) do
{:ok, _} =
Presence.track(socket, "extensions", %{
browser: socket.assigns.browser,
id: socket.assigns.id
})

push(socket, "presence_state", Presence.list(socket))
{:noreply, socket}
end

@impl true
def handle_in("tabs", %{"tabs" => tabs} = payload, socket) do
Extension.add_tabs(socket.assigns.id, tabs)
# broadcast to listeners
{:reply, {:ok, payload}, socket}
end

def handle_in("bookmark-tab", payload, socket) do
params = Map.put(payload, "browser_id", socket.assigns.id)

reply_payload =
case Extension.add_bookmark(params) do
{:ok, _} ->
%{status: "ok"}

{:error, _} ->
%{status: "fail"}
end

{:reply, {:ok, reply_payload}, socket}
end

def handle_in("get-tabs", _payload, socket) do
tabs = Extension.get_tabs(socket.assigns.id)
{:reply, {:ok, tabs}, socket}
end

# It is also common to receive messages from the client and
# broadcast to everyone in the current topic (extension:lobby).
@impl true
def handle_in("shout", payload, socket) do
broadcast(socket, "shout", payload)
{:noreply, socket}
end
end
54 changes: 54 additions & 0 deletions lib/accumulator_web/channels/extension_socket.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
defmodule AccumulatorWeb.ExtensionSocket do
use Phoenix.Socket

# A Socket handler
#
# It's possible to control the websocket connection and
# assign values that can be accessed by your channel topics.

## Channels
# Uncomment the following line to define a "room:*" topic
# pointing to the `AccumulatorWeb.RoomChannel`:
#
# channel "room:*", AccumulatorWeb.RoomChannel
#
# To create a channel file, use the mix task:
#
# mix phx.gen.channel Room
#
# See the [`Channels guide`](https://hexdocs.pm/phoenix/channels.html)
# for further details.
channel "extension", AccumulatorWeb.ExtensionChannel

# Socket params are passed from the client and can
# be used to verify and authenticate a user. After
# verification, you can put default assigns into
# the socket that will be set for all channels, ie
#
# {:ok, assign(socket, :user_id, verified_user_id)}
#
# To deny connection, return `:error` or `{:error, term}`. To control the
# response the client receives in that case, [define an error handler in the
# websocket
# configuration](https://hexdocs.pm/phoenix/Phoenix.Endpoint.html#socket/3-websocket-configuration).
#
# See `Phoenix.Token` documentation for examples in
# performing token verification on connect.
@impl true
def connect(_params, socket, _connect_info) do
{:ok, socket}
end

# Socket IDs are topics that allow you to identify all sockets for a given user:
#
# def id(socket), do: "user_socket:#{socket.assigns.user_id}"
#
# Would allow you to broadcast a "disconnect" event and terminate
# all active sockets and channels for a given user:
#
# Elixir.AccumulatorWeb.Endpoint.broadcast("user_socket:#{user.id}", "disconnect", %{})
#
# Returning `nil` makes this socket anonymous.
@impl true
def id(_socket), do: nil
end
5 changes: 5 additions & 0 deletions lib/accumulator_web/endpoint.ex
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,9 @@ defmodule AccumulatorWeb.Endpoint do
socket "/socket", AccumulatorWeb.UserSocket,
websocket: [connect_info: [session: @session_options]],
longpoll: false

socket "/extension", AccumulatorWeb.ExtensionSocket,
websocket: true,
longpoll: false,
check_origin: false
end
22 changes: 22 additions & 0 deletions priv/cert/selfsigned.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDfDCCAmSgAwIBAgIIRviyvqWz3P8wDQYJKoZIhvcNAQELBQAwQzEaMBgGA1UE
CgwRUGhvZW5peCBGcmFtZXdvcmsxJTAjBgNVBAMMHFNlbGYtc2lnbmVkIHRlc3Qg
Y2VydGlmaWNhdGUwHhcNMjQwNTI1MDAwMDAwWhcNMjUwNTI1MDAwMDAwWjBDMRow
GAYDVQQKDBFQaG9lbml4IEZyYW1ld29yazElMCMGA1UEAwwcU2VsZi1zaWduZWQg
dGVzdCBjZXJ0aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AJ5Yh/7Yje1nLdf0UGvUuyFsA8DoC03a4AirVA65zTb6T+5sD+FfVjLFdj9i+jlr
OA2MDT8dA1gBru1ZQJN7knVxd2+XfSqbL0nfHQiGpRLcrxenKvHObgd3zIumbfHX
RsWzAbclK7jAX2kIMhJmDjzsD3ldgyH5Uvc1Qae88H8s0+2jVJMTe3c743u2flaW
ZbRf5niVYIw2F+VObdUYG0QbhiwcXjj8cN0sPdD8dksgY/dUvJV+mQP7TAVo0F8C
ENF6aTIqshrhDMuUqLvjFGszV96nNrj8R34V134TtQEDV4DVeYr0C1mcfmIA5Gsf
32e8ebVoukWHVvUvKF00KJECAwEAAaN0MHIwDAYDVR0TAQH/BAIwADAOBgNVHQ8B
Af8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQW
BBRJz4SJ/IVx0yJBtUUwJGncxJ2cPjAUBgNVHREEDTALgglsb2NhbGhvc3QwDQYJ
KoZIhvcNAQELBQADggEBAAoWGlHCb8e+oa4iIPkzFE2dDjrG9V34vFQQSr0JOEnQ
6x6H8BjeQCV1yu2mbtrh1RMWE1uibde6thQaUhojAyYnnFBaQo+8tzsx1QGXT1rb
aW/nxGnvL3fckNph4JgsVBnSBiRIt9aQPET5askp0reIUAOYxgdludmsSPmdrWgX
hBHmMlJDIHlWCrtCwQKIEuHkgIhaDAefKSiaF7lVBgODYWPA2f2+8hfewAWGGAti
+RJbN7Pbs590hIKYoKuhAi7rUou0iKj1aCfSf8Ag2vrfUr0VKJYIgC5sYCxy3tEG
vcJx4y90shFhB3UZzluLpbamfD7Y33wDlTZ84d2NRLc=
-----END CERTIFICATE-----

28 changes: 28 additions & 0 deletions priv/cert/selfsigned_key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAnliH/tiN7Wct1/RQa9S7IWwDwOgLTdrgCKtUDrnNNvpP7mwP
4V9WMsV2P2L6OWs4DYwNPx0DWAGu7VlAk3uSdXF3b5d9KpsvSd8dCIalEtyvF6cq
8c5uB3fMi6Zt8ddGxbMBtyUruMBfaQgyEmYOPOwPeV2DIflS9zVBp7zwfyzT7aNU
kxN7dzvje7Z+VpZltF/meJVgjDYX5U5t1RgbRBuGLBxeOPxw3Sw90Px2SyBj91S8
lX6ZA/tMBWjQXwIQ0XppMiqyGuEMy5Sou+MUazNX3qc2uPxHfhXXfhO1AQNXgNV5
ivQLWZx+YgDkax/fZ7x5tWi6RYdW9S8oXTQokQIDAQABAoIBAAjOEvfemlvIaEHx
LbSlTmeQHlBQhupkIJ+SyViNR+ZF+oJfQ23Mk5o8pTPmoNPnDKWiM01eY2R2KYA8
vYzF6xG5RsMviRAAs5s3uyFRfWXkXB8kVky+Zhtns7nTPhtb1W1iZBbHTBxYpCWO
xVwFDUcheEXPJ57QwqaI8VbuuG/V25oUwi/dwto9jc5YzBFXkMvGnSHROkDLFQ8U
wK6z4N7jGxDOc5GLT5Yli/wgd17rFck8GFywUuqZdifVKMigDGxb1jzrELlK/Qrv
jYeZV1UlYhNY/zx1LTz0sF+odIGCj2mpFhV81Dli3L5TRtBdy4N238A2KpTa0UJ6
IfE43IECgYEA2NEJqRDotJKXGkMXGLT4ngCcPxR6pofVHEuGDwK3VgCKNQsKvTjW
bd/1OLrKMotAV07zca/K1Vv7WHCvHlobGenZAZiJqrEhcRySpFWNhAhRHI+J8y30
Uyg1H1MXChTU9lB5hW68WY2wsNM+aUz4cEKADJMLyAdSvhf3XkKztGECgYEAuvZc
ODSrhodThhbGCglB4u8uvD3qxxTqicC/jamcz0FtP4DQsZjOGulTUgfjBoTsRpbu
jcVJk9us75veVsPY292wkkZzuhAUepWxx3v/RQLthqanxM1MXKTXXvJTo+r2+iw7
cmSLK0HX4O7N6+hsq/GzITVD+F7gsiHx/I0x4jECgYEA0RXFGyUTRA+ZZ9oLC+h5
WOV9x9cX8EBNY1vxi8gyxN0AauabFJ8bKhovgOWg190xzwB0A85i7B4n5MHGHp8G
Q5cfjkpreBAZD9teDtvx/MGIduJ1Re2rEAZWND8MmMw+EsrIZcTEHhhlrCAKr8Fq
U9fNZFLpqZxmTqsOAfiRFAECgYAIOXw3EMIW6e8Xr/rISD34wLLanxKr7VSf+LW0
gqieSW+H4p/LoEA42NjMfAJVsBVAybT20Z35/ijuZXnzcSwiB++Tj7vZjImKFvm6
H89L9uQCD2TD+JAKZ0n+KETbqiNxP+7himDA52WaxIaUgSX+rmRF6rTxwSK7U1j0
1jVCkQKBgQCzvwiUC9yMxrgsUN3vcXC57MjbGSp34O2GIKamWa7X5PSigM+vDTzO
iGPwM1VXLzXDUr88ftOiK9CBwPjNlGy86rwjlwTW4kUDn9PC0zhtTXC/+DPmn9uH
s1EypwUQ0u01VUuv1kyA1sKWJd21tqqemzmVgTTraJvr7hs42eWl6A==
-----END RSA PRIVATE KEY-----

12 changes: 12 additions & 0 deletions priv/repo/migrations/20240531211843_extension-bookmarks.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
defmodule :"Elixir.Accumulator.Repo.Migrations.Extension-bookmarks" do
use Ecto.Migration

def change do
create table(:extension_bookmarks) do
add(:url, :text)
add(:title, :text)
add(:browser_id, :string)
timestamps(updated_at: false)
end
end
end

0 comments on commit 0dc104e

Please sign in to comment.