Compare commits
11 Commits
hotfix/des
...
master
Author | SHA1 | Date |
---|---|---|
|
20880e15cb | |
|
6f1200fbd2 | |
|
ebbe1c2fa0 | |
|
45bd5ba81a | |
|
5047ee653b | |
|
c7a9f1d6ae | |
|
a1be189d40 | |
|
beb6c35de9 | |
|
5132f41cad | |
|
9b362d0241 | |
|
7e2eb2cb75 |
|
@ -0,0 +1,157 @@
|
|||
### GNU LESSER GENERAL PUBLIC LICENSE
|
||||
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
<https://fsf.org/>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates the
|
||||
terms and conditions of version 3 of the GNU General Public License,
|
||||
supplemented by the additional permissions listed below.
|
||||
|
||||
#### 0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the
|
||||
GNU General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License, other
|
||||
than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
#### 1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
#### 2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
- a) under this License, provided that you make a good faith effort
|
||||
to ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
- b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
#### 3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from a
|
||||
header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
- a) Give prominent notice with each copy of the object code that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
- b) Accompany the object code with a copy of the GNU GPL and this
|
||||
license document.
|
||||
|
||||
#### 4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that, taken
|
||||
together, effectively do not restrict modification of the portions of
|
||||
the Library contained in the Combined Work and reverse engineering for
|
||||
debugging such modifications, if you also do each of the following:
|
||||
|
||||
- a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
- b) Accompany the Combined Work with a copy of the GNU GPL and this
|
||||
license document.
|
||||
- c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
- d) Do one of the following:
|
||||
- 0. Convey the Minimal Corresponding Source under the terms of
|
||||
this License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
- 1. Use a suitable shared library mechanism for linking with
|
||||
the Library. A suitable mechanism is one that (a) uses at run
|
||||
time a copy of the Library already present on the user's
|
||||
computer system, and (b) will operate properly with a modified
|
||||
version of the Library that is interface-compatible with the
|
||||
Linked Version.
|
||||
- e) Provide Installation Information, but only if you would
|
||||
otherwise be required to provide such information under section 6
|
||||
of the GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the Application
|
||||
with a modified version of the Linked Version. (If you use option
|
||||
4d0, the Installation Information must accompany the Minimal
|
||||
Corresponding Source and Corresponding Application Code. If you
|
||||
use option 4d1, you must provide the Installation Information in
|
||||
the manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.)
|
||||
|
||||
#### 5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the Library
|
||||
side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
- a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities, conveyed under the terms of this License.
|
||||
- b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
#### 6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
as you received it specifies that a certain numbered version of the
|
||||
GNU Lesser General Public License "or any later version" applies to
|
||||
it, you have the option of following the terms and conditions either
|
||||
of that published version or of any later version published by the
|
||||
Free Software Foundation. If the Library as you received it does not
|
||||
specify a version number of the GNU Lesser General Public License, you
|
||||
may choose any version of the GNU Lesser General Public License ever
|
||||
published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
|
@ -0,0 +1,9 @@
|
|||
import type {Config} from '@jest/types';
|
||||
// Sync object
|
||||
const config: Config.InitialOptions = {
|
||||
verbose: true,
|
||||
transform: {
|
||||
‘^.+\\.tsx?$’: ‘ts-jest’,
|
||||
},
|
||||
};
|
||||
export default config;
|
|
@ -24,6 +24,7 @@ import JustPage from './pages/JustPage';
|
|||
import ForPage from './pages/ForPage';
|
||||
import YouPage from './pages/YouPage';
|
||||
import AuthPage from './pages/AuthPage';
|
||||
import PrivacyPolicyPage from './pages/PrivacyPolicyPage';
|
||||
|
||||
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
|
||||
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}})
|
||||
|
@ -43,5 +44,5 @@ liveSocket.connect()
|
|||
window.liveSocket = liveSocket
|
||||
|
||||
window.Components = {
|
||||
SplashPage, JustPage, ForPage, YouPage, AuthPage
|
||||
SplashPage, JustPage, ForPage, YouPage, AuthPage, PrivacyPolicyPage
|
||||
}
|
||||
|
|
|
@ -35,6 +35,11 @@ interface LinkFiles {
|
|||
filetype: string | null;
|
||||
}
|
||||
|
||||
interface GithubEmail {
|
||||
email: string;
|
||||
verified: boolean;
|
||||
}
|
||||
|
||||
const AuthPage = (props: AuthPageProps) => {
|
||||
const { service, recipient, user } = props;
|
||||
|
||||
|
@ -61,13 +66,26 @@ const AuthPage = (props: AuthPageProps) => {
|
|||
};
|
||||
|
||||
const userEmails = (): string[] => {
|
||||
if (!user?.emails) return [];
|
||||
if (user.emails.length <= 0) return [];
|
||||
return user
|
||||
? user.emails
|
||||
.filter((email) => email.verified)
|
||||
.map((email) => email.email)
|
||||
.filter(verifiedUserEmails)
|
||||
.map((email) => (typeof email == "string" ? email : email.email))
|
||||
: [];
|
||||
};
|
||||
|
||||
const isGithubEmail = (email: string | GithubEmail): email is GithubEmail =>
|
||||
(email as GithubEmail).verified !== undefined;
|
||||
|
||||
const verifiedUserEmails = (email: string | GithubEmail) => {
|
||||
if (isGithubEmail(email)) {
|
||||
return (email as GithubEmail).verified;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
const retrieveLink = async (): Promise<LinkFiles | null> => {
|
||||
const urlSegments = new URL(document.URL).pathname.split("/");
|
||||
const linkId = urlSegments.pop() || urlSegments.pop();
|
||||
|
@ -75,6 +93,10 @@ const AuthPage = (props: AuthPageProps) => {
|
|||
alert("Could not find intended link in URL");
|
||||
return null;
|
||||
}
|
||||
if (!user) {
|
||||
// no need to retrieve link if they weren't authenticated
|
||||
return null;
|
||||
}
|
||||
|
||||
const linkResponse = await fetch(`/links/${linkId}`);
|
||||
let linkData: IntendedLink | null;
|
||||
|
@ -190,10 +212,13 @@ const AuthPage = (props: AuthPageProps) => {
|
|||
small
|
||||
style={{ color: "#CCCCCC", fontSize: "1.4rem", textAlign: "left" }}
|
||||
>
|
||||
Hello {user.name}, you are logged in to{" "}
|
||||
<span style={{ color: "#A849CF" }}>{capitalize(service)}</span> as{" "}
|
||||
<span style={{ color: "#32EFE7" }}>{user.username}</span>. This account
|
||||
has the following emails associated with it:
|
||||
Hello{user.name ? ` ${user.name}` : ""}! You are logged in to{" "}
|
||||
<span style={{ color: "#A849CF" }}>{capitalize(service)}</span>
|
||||
{user.username ? " as " : ""}
|
||||
<span style={{ color: "#32EFE7" }}>
|
||||
{user.username ? `${user.username}` : ""}
|
||||
</span>
|
||||
. This account has the following emails associated with it:
|
||||
<br />
|
||||
<br />
|
||||
<span style={{ color: "#32EFE7" }}>{userEmails().join(", ")}</span>
|
||||
|
|
|
@ -34,12 +34,6 @@ const ForPage = (props: ForPageProps) => {
|
|||
};
|
||||
|
||||
const postContacts = async () => {
|
||||
// const fragmentData = window.location.hash.split('.');
|
||||
// if (fragmentData.length <= 0) {
|
||||
// alert("No key found in fragment URI");
|
||||
// return;
|
||||
// }
|
||||
|
||||
const linkId = sessionStorage.getItem("link_id");
|
||||
if (!linkId) {
|
||||
alert("No created link found in storage");
|
||||
|
@ -101,6 +95,7 @@ const ForPage = (props: ForPageProps) => {
|
|||
value={serviceSelect}
|
||||
>
|
||||
<option value="github">Github</option>
|
||||
<option value="google">Gmail</option>
|
||||
</Select>
|
||||
<Spacer space="3rem" />
|
||||
<SpaceBetweenContainer>
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
import React from "react";
|
||||
|
||||
import {
|
||||
CenteredContainer,
|
||||
Header1,
|
||||
Header3,
|
||||
GlobalStyle,
|
||||
} from "@intended/intended-ui";
|
||||
|
||||
const PrivacyPolicyPage = () => {
|
||||
return (
|
||||
<React.StrictMode>
|
||||
<GlobalStyle />
|
||||
<CenteredContainer
|
||||
fullscreen
|
||||
style={{
|
||||
background: "none",
|
||||
height: "auto",
|
||||
}}
|
||||
>
|
||||
<CenteredContainer wide style={{ maxWidth: "800px" }}>
|
||||
<Header1>Privacy Policy</Header1>
|
||||
<Header3
|
||||
small
|
||||
style={{
|
||||
color: "#CCCCCC",
|
||||
textAlign: "left",
|
||||
fontSize: "18px",
|
||||
lineHeight: 1.6,
|
||||
}}
|
||||
>
|
||||
<p>
|
||||
This instance of Intended Link collects as little data as
|
||||
necessary to provide its service. It can not read the secret
|
||||
message and secret file, and all data associated with a link is
|
||||
deleted once it expires.
|
||||
</p>
|
||||
<p>
|
||||
Each link created will store the recipient's username or email and
|
||||
its associated service for authorization purposes. It will store
|
||||
the filename and filetype of the secret file, if it exists, to
|
||||
make it easier for users to download and use the file once it's
|
||||
decrypted. We store the timestamps of when the Link was created
|
||||
and updated, along with when the link should expire.
|
||||
</p>
|
||||
<p>
|
||||
When you authenticate with one of our supported OAuth providers,
|
||||
we receive the third party's response, and if verification was
|
||||
successful, we store the account's username and verified emails in
|
||||
a short-lived session store. This data is then used to determine
|
||||
whether the user is permitted to download the link's associated
|
||||
secret message and file.
|
||||
</p>
|
||||
<p>This software is licensed under LGPL.</p>
|
||||
</Header3>
|
||||
</CenteredContainer>
|
||||
</CenteredContainer>
|
||||
</React.StrictMode>
|
||||
);
|
||||
};
|
||||
|
||||
export default PrivacyPolicyPage;
|
File diff suppressed because it is too large
Load Diff
|
@ -4,7 +4,8 @@
|
|||
"license": "MIT",
|
||||
"scripts": {
|
||||
"deploy": "webpack --mode production",
|
||||
"watch": "webpack --mode development --watch"
|
||||
"watch": "webpack --mode development --watch",
|
||||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@intended/intended-ui": "0.1.26",
|
||||
|
@ -20,6 +21,7 @@
|
|||
"@babel/core": "^7.0.0",
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"@babel/preset-react": "^7.16.0",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/phoenix": "^1.5.3",
|
||||
"@types/react": "^17.0.37",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
|
@ -27,12 +29,14 @@
|
|||
"copy-webpack-plugin": "^5.1.1",
|
||||
"css-loader": "^3.4.2",
|
||||
"hard-source-webpack-plugin": "^0.13.1",
|
||||
"jest": "^27.5.1",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"node-sass": "^4.13.1",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.1",
|
||||
"sass-loader": "^8.0.2",
|
||||
"source-map-loader": "^3.0.0",
|
||||
"terser-webpack-plugin": "^2.3.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-loader": "8.2.0",
|
||||
"typescript": "^4.5.2",
|
||||
"webpack": "^4.41.5",
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 156 KiB |
|
@ -0,0 +1,3 @@
|
|||
## Implementation Details
|
||||
|
||||
Write info on what we'd use, or just start adding in the tests and remove this file.
|
|
@ -30,7 +30,9 @@ config :phoenix, :json_library, Jason
|
|||
|
||||
config :ueberauth, Ueberauth,
|
||||
providers: [
|
||||
github: {Ueberauth.Strategy.Github, [default_scope: "user:email", allow_private_emails: true]}
|
||||
github:
|
||||
{Ueberauth.Strategy.Github, [default_scope: "user:email", allow_private_emails: true]},
|
||||
google: {Ueberauth.Strategy.Google, [default_scope: "email"]}
|
||||
]
|
||||
|
||||
config :waffle,
|
||||
|
|
|
@ -34,6 +34,10 @@ config :ueberauth, Ueberauth.Strategy.Github.OAuth,
|
|||
client_id: System.get_env("GH_OAUTH_ID"),
|
||||
client_secret: System.get_env("GH_OAUTH_SECRET")
|
||||
|
||||
config :ueberauth, Ueberauth.Strategy.Google.OAuth,
|
||||
client_id: System.get_env("GOOGLE_OAUTH_ID"),
|
||||
client_secret: System.get_env("GOOGLE_OAUTH_SECRET")
|
||||
|
||||
# ## Using releases (Elixir v1.9+)
|
||||
#
|
||||
# If you are doing OTP releases, you need to instruct Phoenix
|
||||
|
|
|
@ -6,7 +6,6 @@ defmodule Entendu.UserFromAuth do
|
|||
require Jason
|
||||
|
||||
alias Ueberauth.Auth
|
||||
alias Entendu.Links.Link
|
||||
|
||||
def find_or_create(%Auth{} = auth) do
|
||||
{:ok, basic_info(auth)}
|
||||
|
@ -71,7 +70,22 @@ defmodule Entendu.UserFromAuth do
|
|||
do: email_matches?(recipient, emails) || username_matches?(recipient, username)
|
||||
|
||||
defp email_matches?(recipient, emails),
|
||||
do: emails |> Enum.any?(&(&1["verified"] == true and &1["email"] == recipient))
|
||||
do:
|
||||
emails
|
||||
|> Enum.filter(&only_verified_emails/1)
|
||||
|> Enum.map(&retrieve_email/1)
|
||||
|> Enum.any?(&(&1 == recipient))
|
||||
|
||||
# Github lists unverified emails and need to be filtered out
|
||||
defp only_verified_emails(%{"verified" => is_verified}), do: is_verified
|
||||
|
||||
defp only_verified_emails(_), do: true
|
||||
|
||||
defp retrieve_email(%{"email" => email}), do: email
|
||||
|
||||
defp retrieve_email(email), do: email
|
||||
|
||||
defp username_matches?(_recipient, nil), do: false
|
||||
|
||||
defp username_matches?(recipient, username), do: String.trim(username) === recipient
|
||||
end
|
||||
|
|
|
@ -8,8 +8,6 @@ defmodule EntenduWeb.AuthController do
|
|||
plug Ueberauth
|
||||
|
||||
alias Entendu.UserFromAuth
|
||||
alias EntenduWeb.LinkView
|
||||
alias Entendu.EncryptedLink
|
||||
|
||||
def delete(conn, _params) do
|
||||
conn
|
||||
|
@ -27,10 +25,8 @@ defmodule EntenduWeb.AuthController do
|
|||
def callback(%{assigns: %{ueberauth_auth: auth}} = conn, _params) do
|
||||
link = get_session(conn, :intended_link)
|
||||
|
||||
with %{id: link_id, recipient: recipient} <- link,
|
||||
with %{id: link_id} <- link,
|
||||
{:ok, user} <- UserFromAuth.find_or_create(auth) do
|
||||
# TODO: send over encrypted data that the frontend can decrypt
|
||||
|
||||
conn
|
||||
|> put_session(:current_user, user)
|
||||
|> configure_session(renew: true)
|
||||
|
|
|
@ -9,8 +9,6 @@ defmodule EntenduWeb.LinkController do
|
|||
alias Entendu.Links
|
||||
alias Links.Link
|
||||
alias EntenduWeb.FallbackController
|
||||
alias Entendu.EncryptedLink
|
||||
alias Entendu.UserFromAuth
|
||||
alias EntenduWeb.Plugs.AuthorizeLink
|
||||
|
||||
plug AuthorizeLink when action in [:text, :file]
|
||||
|
@ -18,7 +16,8 @@ defmodule EntenduWeb.LinkController do
|
|||
action_fallback(FallbackController)
|
||||
|
||||
def just_page(conn, _params) do
|
||||
render(conn, "just.html")
|
||||
conn
|
||||
|> render("just.html")
|
||||
end
|
||||
|
||||
def just(conn, params) do
|
||||
|
@ -46,7 +45,7 @@ defmodule EntenduWeb.LinkController do
|
|||
end
|
||||
|
||||
def auth_page(conn, %{"id" => link_id}) do
|
||||
with %Link{id: id, service: service, recipient: recipient} = link <- Links.get_link(link_id) do
|
||||
with %Link{id: id, service: service, recipient: recipient} <- Links.get_link(link_id) do
|
||||
conn
|
||||
|> put_session(:intended_link, %{id: id, service: service, recipient: recipient})
|
||||
|> render("auth.html", %{intended_link: %{service: service, recipient: recipient}})
|
||||
|
|
|
@ -10,4 +10,9 @@ defmodule EntenduWeb.PageController do
|
|||
|> clear_session()
|
||||
|> render("index.html")
|
||||
end
|
||||
|
||||
def privacy(conn, _params) do
|
||||
conn
|
||||
|> render("privacy_policy.html")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,11 +2,9 @@ defmodule EntenduWeb.Plugs.AuthorizeLink do
|
|||
import Plug.Conn
|
||||
use EntenduWeb, :controller
|
||||
|
||||
alias Entendu.Repo
|
||||
alias Entendu.UserFromAuth
|
||||
alias Entendu.Links
|
||||
alias Entendu.Links.Link
|
||||
alias EntenduWeb.FallbackController
|
||||
alias EntenduWeb.ErrorView
|
||||
|
||||
def init(_params) do
|
||||
|
@ -23,7 +21,7 @@ defmodule EntenduWeb.Plugs.AuthorizeLink do
|
|||
if !user do
|
||||
conn
|
||||
|> put_status(403)
|
||||
|> put_view(EntenduWeb.ErrorView)
|
||||
|> put_view(ErrorView)
|
||||
|> render("error_code.json", message: "Unauthorized", code: 403)
|
||||
|> halt
|
||||
else
|
||||
|
@ -35,21 +33,21 @@ defmodule EntenduWeb.Plugs.AuthorizeLink do
|
|||
nil ->
|
||||
conn
|
||||
|> put_status(404)
|
||||
|> put_view(EntenduWeb.ErrorView)
|
||||
|> put_view(ErrorView)
|
||||
|> render("error_code.json", message: "Link could not be found", code: 404)
|
||||
|> halt
|
||||
|
||||
false ->
|
||||
conn
|
||||
|> put_status(403)
|
||||
|> put_view(EntenduWeb.ErrorView)
|
||||
|> put_view(ErrorView)
|
||||
|> render("error_code.json", message: "Unauthorized", code: 403)
|
||||
|> halt
|
||||
|
||||
{:error, reason} ->
|
||||
conn
|
||||
|> put_status(422)
|
||||
|> put_view(EntenduWeb.ErrorView)
|
||||
|> put_view(ErrorView)
|
||||
|> render("error_code.json", message: reason, code: 422)
|
||||
|> halt
|
||||
end
|
||||
|
|
|
@ -35,6 +35,8 @@ defmodule EntenduWeb.Router do
|
|||
post "/just/for", LinkController, :for
|
||||
get "/just/for/you", LinkController, :you_page
|
||||
get "/just/for/you/:id", LinkController, :auth_page
|
||||
|
||||
get "/privacy-policy", PageController, :privacy
|
||||
end
|
||||
|
||||
scope "/auth", EntenduWeb do
|
||||
|
|
|
@ -4,8 +4,20 @@
|
|||
<meta charset="utf-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<!-- Essential META Tags -->
|
||||
<meta property="og:title" content="Intended Link">
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="https://intended.link/images/thumbnail.jpg">
|
||||
<meta property="og:url" content="https://intended.link">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
|
||||
<!-- Non-Essential, But Recommended -->
|
||||
<meta property="og:description" content="Securely send private messages to social media accounts.">
|
||||
<meta property="og:site_name" content="Intended Link">
|
||||
<meta name="twitter:image:alt" content="Preview of splash page">
|
||||
|
||||
<%= csrf_meta_tag() %>
|
||||
<%= live_title_tag assigns[:page_title] || "Entendu", suffix: " · Phoenix Framework" %>
|
||||
<%= live_title_tag assigns[:page_title] || "Intended Link", suffix: "" %>
|
||||
<link phx-track-static rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
|
||||
<script defer phx-track-static type="text/javascript" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script>
|
||||
</head>
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<section>
|
||||
<%= react_component("Components.PrivacyPolicyPage") %>
|
||||
</section>
|
|
@ -36,7 +36,7 @@ defmodule Entendu.EncryptedLink do
|
|||
# end
|
||||
|
||||
# Override the storage directory:
|
||||
def storage_dir(version, {_file, scope}) do
|
||||
def storage_dir(_version, {_file, scope}) do
|
||||
"priv/uploads/links/#{scope.id}"
|
||||
end
|
||||
|
||||
|
|
1
mix.exs
1
mix.exs
|
@ -50,6 +50,7 @@ defmodule Entendu.MixProject do
|
|||
{:libcluster, "~> 3.2"},
|
||||
{:ueberauth, "~> 0.7.0"},
|
||||
{:ueberauth_github, "~> 0.8.1"},
|
||||
{:ueberauth_google, "~> 0.10.1"},
|
||||
{:react_phoenix, "~> 1.3"},
|
||||
{:params, "~> 2.2"},
|
||||
{:waffle, "~> 1.1"},
|
||||
|
|
1
mix.lock
1
mix.lock
|
@ -41,6 +41,7 @@
|
|||
"telemetry_poller": {:hex, :telemetry_poller, "0.5.1", "21071cc2e536810bac5628b935521ff3e28f0303e770951158c73eaaa01e962a", [:rebar3], [{:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4cab72069210bc6e7a080cec9afffad1b33370149ed5d379b81c7c5f0c663fd4"},
|
||||
"ueberauth": {:hex, :ueberauth, "0.7.0", "9c44f41798b5fa27f872561b6f7d2bb0f10f03fdd22b90f454232d7b087f4b75", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "2efad9022e949834f16cc52cd935165049d81fa9e925690f91035c2e4b58d905"},
|
||||
"ueberauth_github": {:hex, :ueberauth_github, "0.8.1", "0be487b5afc29bc805fa5e31636f37c8f09d5159ef73fc08c4c7a98c9cfe2c18", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.7.0", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "143d6130b945ea9bdbd0ef94987f40788f1d7e8090decbfc0722773155e7a74a"},
|
||||
"ueberauth_google": {:hex, :ueberauth_google, "0.10.1", "db7bd2d99d2ff38e7449042a08d9560741b0dcaf1c31191729b97188b025465e", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.7.0", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "b799f547d279bb836e1f7039fc9fbb3a9d008a695e2a25bd06bffe591a168ba1"},
|
||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
||||
"waffle": {:hex, :waffle, "1.1.5", "11b8b41c9dc46a21c8e1e619e1e9048d18d166b57b33d1fada8e11fcd4e678b3", [:mix], [{:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:ex_aws_s3, "~> 2.1", [hex: :ex_aws_s3, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: false]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "68e6f92b457b13c71e33cc23f7abb60446a01515dc6618b7d493d8cd466b1f39"},
|
||||
"waffle_ecto": {:hex, :waffle_ecto, "0.0.11", "3d9581b3dfc83964ad968ef6bbf31132b5e6959c542a74c49e2a2245a9521048", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:waffle, "~> 1.0", [hex: :waffle, repo: "hexpm", optional: false]}], "hexpm", "626c2832ba94e20840532e609d3af70526d18ff9dfe1b352afb3fbabedb31a7e"},
|
||||
|
|
Loading…
Reference in New Issue