Skip to content

Instantly share code, notes, and snippets.

View wttj-tech's full-sized avatar

WTTJ Tech wttj-tech

View GitHub Profile
@wttj-tech
wttj-tech / 8811799dee05-hint-index.js
Created March 24, 2022 15:26
How we implemented our open-source design system
export const Hint = styled.div`
/* Values from the theme file (see below) */
${th('hints')};
/* Directly check the color from theme object */
color: dark.900;
margin-top: sm;
display: flex;
align-items: center;
/* get system props from xstyled */
${system};
@wttj-tech
wttj-tech / 8811799dee05-hint-theme.js
Created March 24, 2022 15:28
How we implemented our open-source design system
/* get all theme entries from core to pass to hint theming file */
export const getHints = theme => {
const { colors, fontSizes, fontWeights } = theme
return {
color: colors.light[500],
fontSize: fontSizes.body4,
fontWeight: fontWeights.regular,
}
}
def create(conn, %{"user" => %{"email" => email}}) do
if user = Accounts.get_user_by_email(email) do
Accounts.deliver_user_reset_password_instructions(
user,
&Routes.user_reset_password_url(conn, :edit, &1)
)
end
# In order to prevent user enumeration attacks, regardless of the outcome, show an impartial success/error message.
conn
@wttj-tech
wttj-tech / 8961f60effc7-user-noverify.ex
Last active March 28, 2022 08:37
Prevent timing attack
@doc """
Verifies the password.
If there is no user or the user doesn't have a password, we call
`Bcrypt.no_user_verify/0` to avoid timing attacks.
"""
def valid_password?(%TestAuth.Accounts.User{hashed_password: hashed_password}, password)
when is_binary(hashed_password) and byte_size(password) > 0 do
Bcrypt.verify_pass(password, hashed_password)
end
defmodule User do
def changeset(user, attrs) do
user
|> cast(attrs, [:password])
|> validate_length(:password, min: 12)
|> validate_format(:password, ~r/[a-z]/, message: "at least one lower case character")
|> validate_format(:password, ~r/[A-Z]/, message: "at least one upper case character")
|> validate_format(:password, ~r/[!?@#$%^&*_0-9]/, message: "at least one digit or punctuation character")
end
end
defmodule MyAppWeb.Router do
use Phoenix.Router
....
pipeline "auth" do
# Where we set :current_user
plug :require_authenticated_user
# Check password validity
plug MyApp.PasswordRotation
end
@wttj-tech
wttj-tech / 8961f60effc7-password-history.ex
Created March 28, 2022 08:47
Password: prevent reuse
defmodule MyApp.Auth do
@doc """
## Example
iex> Bcrypt.hash_pwd_salt("azerty")
"$2b$12$24jRrK0ZzPqWXAAnZrQ1MOYF6QoMPwZ6knuGba2yyvy1wIFd9fvRW"
iex> old_encrypted_password = Bcrypt.hash_pwd_salt("azerty")
"$2b$12$Voc7tE9Ry926Siau6mQsvOFLNpGVKkkRrNfbsT0goYkmpCqZLIPI6"
iex> compare_password("azerty", old_encrypted_password)
true
iex> compare_password("Hello world", old_encrypted_password)
defmodule WttjApi.Repo.Migrations.RenameUsersTitle do
use Ecto.Migration
def change do
rename table(:users), :title, to: :gender
end
end
defmodule WttjApi.Accounts.User do
use Ecto.Schema
schema “users” do
field(:gender, :string)
end
end
defmodule WttjApi.Repo.Migrations.AddGenderToUsers do
use Ecto.Migration
def change do
alter table(:users) do
add_if_not_exists :gender, :string
end
end
end