diff --git a/app/actions/definitions/teams.tsx b/app/actions/definitions/teams.tsx
index 06bcbbbb7c..3eae35035f 100644
--- a/app/actions/definitions/teams.tsx
+++ b/app/actions/definitions/teams.tsx
@@ -1,7 +1,9 @@
import { PlusIcon } from "outline-icons";
import * as React from "react";
import styled from "styled-components";
+import { stringToColor } from "@shared/utils/color";
import TeamNew from "~/scenes/TeamNew";
+import TeamLogo from "~/components/TeamLogo";
import { createAction } from "~/actions";
import { loadSessionsFromCookie } from "~/hooks/useSessions";
import { TeamSection } from "../sections";
@@ -11,7 +13,18 @@ export const switchTeamList = getSessions().map((session) => {
name: session.name,
section: TeamSection,
keywords: "change switch workspace organization team",
- icon: () => ,
+ icon: () => (
+
+ ),
visible: ({ currentTeamId }) => currentTeamId !== session.teamId,
perform: () => (window.location.href = session.url),
});
@@ -55,10 +68,9 @@ function getSessions(params?: { exclude?: string }) {
return otherSessions;
}
-const Logo = styled("img")`
+const StyledTeamLogo = styled(TeamLogo)`
border-radius: 2px;
- width: 24px;
- height: 24px;
+ border: 0;
`;
export const rootTeamActions = [switchTeam, createTeam];
diff --git a/app/components/Avatar/Avatar.tsx b/app/components/Avatar/Avatar.tsx
index 5d26fc8ff6..4d694718f8 100644
--- a/app/components/Avatar/Avatar.tsx
+++ b/app/components/Avatar/Avatar.tsx
@@ -1,14 +1,21 @@
import * as React from "react";
import styled from "styled-components";
-import User from "~/models/User";
import useBoolean from "~/hooks/useBoolean";
+import Initials from "./Initials";
import placeholder from "./placeholder.png";
+export interface IAvatar {
+ avatarUrl: string | null;
+ color: string;
+ initial: string;
+ id: string;
+}
+
type Props = {
- src: string;
size: number;
+ src?: string;
icon?: React.ReactNode;
- user?: User;
+ model?: IAvatar;
alt?: string;
showBorder?: boolean;
onClick?: React.MouseEventHandler;
@@ -16,20 +23,28 @@ type Props = {
};
function Avatar(props: Props) {
- const { src, icon, showBorder, ...rest } = props;
-
+ const { icon, showBorder, model, ...rest } = props;
+ const src = props.src || model?.avatarUrl;
const [error, handleError] = useBoolean(false);
return (
-
-
+
+ {src ? (
+
+ ) : model ? (
+
+ {model.initial}
+
+ ) : (
+
+ )}
{icon && {icon}}
-
+
);
}
@@ -37,7 +52,7 @@ Avatar.defaultProps = {
size: 24,
};
-const AvatarWrapper = styled.div`
+const Relative = styled.div`
position: relative;
`;
diff --git a/app/components/Avatar/AvatarWithPresence.tsx b/app/components/Avatar/AvatarWithPresence.tsx
index a66278d7a4..7cbe5c5bd8 100644
--- a/app/components/Avatar/AvatarWithPresence.tsx
+++ b/app/components/Avatar/AvatarWithPresence.tsx
@@ -51,7 +51,7 @@ function AvatarWithPresence({
$isObserving={isObserving}
$color={user.color}
>
-
+
>
diff --git a/app/components/Avatar/Initials.tsx b/app/components/Avatar/Initials.tsx
new file mode 100644
index 0000000000..bb46dfef76
--- /dev/null
+++ b/app/components/Avatar/Initials.tsx
@@ -0,0 +1,27 @@
+import styled from "styled-components";
+import Flex from "~/components/Flex";
+
+const Initials = styled(Flex)<{
+ color?: string;
+ size: number;
+ $showBorder?: boolean;
+}>`
+ align-items: center;
+ justify-content: center;
+ border-radius: 50%;
+ width: 100%;
+ height: 100%;
+ color: #fff;
+ background-color: ${(props) => props.color};
+ width: ${(props) => props.size}px;
+ height: ${(props) => props.size}px;
+ border-radius: 50%;
+ border: 2px solid
+ ${(props) =>
+ props.$showBorder === false ? "transparent" : props.theme.background};
+ flex-shrink: 0;
+ font-size: ${(props) => props.size / 2}px;
+ font-weight: 500;
+`;
+
+export default Initials;
diff --git a/app/components/DocumentViews.tsx b/app/components/DocumentViews.tsx
index 62ec57d909..a836e0545d 100644
--- a/app/components/DocumentViews.tsx
+++ b/app/components/DocumentViews.tsx
@@ -43,10 +43,10 @@ function DocumentViews({ document, isOpen }: Props) {
{
- const view = documentViews.find((v) => v.user.id === item.id);
- const isPresent = presentIds.includes(item.id);
- const isEditing = editingIds.includes(item.id);
+ renderItem={(model: User) => {
+ const view = documentViews.find((v) => v.user.id === model.id);
+ const isPresent = presentIds.includes(model.id);
+ const isEditing = editingIds.includes(model.id);
const subtitle = isPresent
? isEditing
? t("Currently editing")
@@ -58,10 +58,10 @@ function DocumentViews({ document, isOpen }: Props) {
});
return (
}
+ image={}
border={false}
small
/>
diff --git a/app/components/EventListItem.tsx b/app/components/EventListItem.tsx
index ff22994a7e..a9fdaac831 100644
--- a/app/components/EventListItem.tsx
+++ b/app/components/EventListItem.tsx
@@ -142,7 +142,7 @@ const EventListItem = ({ event, latest, document, ...rest }: Props) => {
onClick={handleTimeClick}
/>
}
- image={}
+ image={}
subtitle={
{icon}
diff --git a/app/components/Facepile.tsx b/app/components/Facepile.tsx
index a3e117edec..9bd058d21b 100644
--- a/app/components/Facepile.tsx
+++ b/app/components/Facepile.tsx
@@ -39,7 +39,7 @@ function Facepile({
}
function DefaultAvatar(user: User) {
- return ;
+ return ;
}
const AvatarWrapper = styled.div`
diff --git a/app/components/Sidebar/App.tsx b/app/components/Sidebar/App.tsx
index fad3164a3f..4385bf0a79 100644
--- a/app/components/Sidebar/App.tsx
+++ b/app/components/Sidebar/App.tsx
@@ -63,14 +63,7 @@ function AppSidebar() {
- }
+ image={}
showDisclosure
/>
)}
@@ -139,11 +132,6 @@ function AppSidebar() {
);
}
-const StyledTeamLogo = styled(TeamLogo)`
- margin-right: 4px;
- background: white;
-`;
-
const Drafts = styled(Text)`
margin: 0 4px;
`;
diff --git a/app/components/Sidebar/Sidebar.tsx b/app/components/Sidebar/Sidebar.tsx
index e02d10bd5d..9aca1a545f 100644
--- a/app/components/Sidebar/Sidebar.tsx
+++ b/app/components/Sidebar/Sidebar.tsx
@@ -178,7 +178,7 @@ const Sidebar = React.forwardRef(
image={
diff --git a/app/components/TeamLogo.ts b/app/components/TeamLogo.ts
index 4df19eafa8..6cadfd4255 100644
--- a/app/components/TeamLogo.ts
+++ b/app/components/TeamLogo.ts
@@ -1,10 +1,7 @@
import styled from "styled-components";
+import Avatar from "./Avatar";
-const TeamLogo = styled.img<{ width?: number; height?: number; size?: string }>`
- width: ${(props) =>
- props.width ? `${props.width}px` : props.size || "auto"};
- height: ${(props) =>
- props.height ? `${props.height}px` : props.size || "38px"};
+const TeamLogo = styled(Avatar)`
border-radius: 4px;
border: 1px solid ${(props) => props.theme.divider};
overflow: hidden;
diff --git a/app/models/Team.ts b/app/models/Team.ts
index fd2be58856..02248a6bee 100644
--- a/app/models/Team.ts
+++ b/app/models/Team.ts
@@ -1,5 +1,6 @@
import { computed, observable } from "mobx";
import { TeamPreference, TeamPreferences } from "@shared/types";
+import { stringToColor } from "@shared/utils/color";
import BaseModel from "./BaseModel";
import Field from "./decorators/Field";
@@ -69,6 +70,16 @@ class Team extends BaseModel {
return "SSO";
}
+ @computed
+ get color(): string {
+ return stringToColor(this.id);
+ }
+
+ @computed
+ get initial(): string {
+ return this.name ? this.name[0] : "?";
+ }
+
/**
* Returns whether this team is using a separate editing mode behind an "Edit"
* button rather than seamless always-editing.
diff --git a/app/models/User.ts b/app/models/User.ts
index ceb7372dba..5d70623db5 100644
--- a/app/models/User.ts
+++ b/app/models/User.ts
@@ -40,6 +40,11 @@ class User extends ParanoidModel {
isSuspended: boolean;
+ @computed
+ get initial(): string {
+ return this.name ? this.name[0] : "?";
+ }
+
@computed
get isInvited(): boolean {
return !this.lastActiveAt;
diff --git a/app/scenes/Collection/MembershipPreview.tsx b/app/scenes/Collection/MembershipPreview.tsx
index 36f08b5337..f3e74ccf83 100644
--- a/app/scenes/Collection/MembershipPreview.tsx
+++ b/app/scenes/Collection/MembershipPreview.tsx
@@ -104,18 +104,16 @@ const MembershipPreview = ({ collection, limit = 8 }: Props) => {
users={sortBy(collectionUsers, "lastActiveAt")}
overflow={overflow}
limit={limit}
- renderAvatar={(user) => (
-
- )}
+ renderAvatar={(user) => }
/>
);
};
-const StyledAvatar = styled(Avatar)<{ user: User }>`
+const StyledAvatar = styled(Avatar)<{ model: User }>`
transition: opacity 250ms ease-in-out;
- opacity: ${(props) => (props.user.isRecentlyActive ? 1 : 0.5)};
+ opacity: ${(props) => (props.model.isRecentlyActive ? 1 : 0.5)};
`;
export default observer(MembershipPreview);
diff --git a/app/scenes/CollectionPermissions/components/MemberListItem.tsx b/app/scenes/CollectionPermissions/components/MemberListItem.tsx
index 06a7d0c24b..3176a21b5f 100644
--- a/app/scenes/CollectionPermissions/components/MemberListItem.tsx
+++ b/app/scenes/CollectionPermissions/components/MemberListItem.tsx
@@ -49,7 +49,7 @@ const MemberListItem = ({
{user.isAdmin && {t("Admin")}}
>
}
- image={}
+ image={}
actions={
{onUpdate && (
diff --git a/app/scenes/CollectionPermissions/components/UserListItem.tsx b/app/scenes/CollectionPermissions/components/UserListItem.tsx
index 925fea75a8..eecd5ae593 100644
--- a/app/scenes/CollectionPermissions/components/UserListItem.tsx
+++ b/app/scenes/CollectionPermissions/components/UserListItem.tsx
@@ -21,7 +21,7 @@ const UserListItem = ({ user, onAdd, canEdit }: Props) => {
return (
}
+ image={}
subtitle={
<>
{user.lastActiveAt ? (
diff --git a/app/scenes/GroupMembers/components/GroupMemberListItem.tsx b/app/scenes/GroupMembers/components/GroupMemberListItem.tsx
index f470585936..3c7a1fad5e 100644
--- a/app/scenes/GroupMembers/components/GroupMemberListItem.tsx
+++ b/app/scenes/GroupMembers/components/GroupMemberListItem.tsx
@@ -35,7 +35,7 @@ const GroupMemberListItem = ({ user, onRemove, onAdd }: Props) => {
{user.isAdmin && {t("Admin")}}
>
}
- image={}
+ image={}
actions={
{onRemove && }
diff --git a/app/scenes/GroupMembers/components/UserListItem.tsx b/app/scenes/GroupMembers/components/UserListItem.tsx
index 925fea75a8..eecd5ae593 100644
--- a/app/scenes/GroupMembers/components/UserListItem.tsx
+++ b/app/scenes/GroupMembers/components/UserListItem.tsx
@@ -21,7 +21,7 @@ const UserListItem = ({ user, onAdd, canEdit }: Props) => {
return (
}
+ image={}
subtitle={
<>
{user.lastActiveAt ? (
diff --git a/app/scenes/Login/index.tsx b/app/scenes/Login/index.tsx
index dab5eeb862..81adf346e4 100644
--- a/app/scenes/Login/index.tsx
+++ b/app/scenes/Login/index.tsx
@@ -169,7 +169,7 @@ function Login({ children }: Props) {
/>
{config.logo ? (
-
+
) : (
)}
diff --git a/app/scenes/Settings/Details.tsx b/app/scenes/Settings/Details.tsx
index b45a5e185a..3f2e769ea9 100644
--- a/app/scenes/Settings/Details.tsx
+++ b/app/scenes/Settings/Details.tsx
@@ -26,7 +26,6 @@ function Details() {
const form = useRef(null);
const [name, setName] = useState(team.name);
const [subdomain, setSubdomain] = useState(team.subdomain);
- const [avatarUrl, setAvatarUrl] = useState(team.avatarUrl);
const [defaultCollectionId, setDefaultCollectionId] = useState(
team.defaultCollectionId
);
@@ -40,7 +39,6 @@ function Details() {
try {
await auth.updateTeam({
name,
- avatarUrl,
subdomain,
defaultCollectionId,
});
@@ -53,7 +51,7 @@ function Details() {
});
}
},
- [auth, name, avatarUrl, subdomain, defaultCollectionId, showToast, t]
+ [auth, name, subdomain, defaultCollectionId, showToast, t]
);
const handleNameChange = React.useCallback(
@@ -71,7 +69,6 @@ function Details() {
);
const handleAvatarUpload = async (avatarUrl: string) => {
- setAvatarUrl(avatarUrl);
await auth.updateTeam({
avatarUrl,
});
@@ -115,7 +112,7 @@ function Details() {
diff --git a/app/scenes/Settings/Profile.tsx b/app/scenes/Settings/Profile.tsx
index 2bd29a1ed1..bc804be060 100644
--- a/app/scenes/Settings/Profile.tsx
+++ b/app/scenes/Settings/Profile.tsx
@@ -18,7 +18,6 @@ const Profile = () => {
const user = useCurrentUser();
const form = React.useRef(null);
const [name, setName] = React.useState(user.name || "");
- const [avatarUrl, setAvatarUrl] = React.useState(user.avatarUrl);
const { showToast } = useToasts();
const { t } = useTranslation();
@@ -28,7 +27,6 @@ const Profile = () => {
try {
await auth.updateUser({
name,
- avatarUrl,
});
showToast(t("Profile saved"), {
type: "success",
@@ -45,7 +43,6 @@ const Profile = () => {
};
const handleAvatarUpload = async (avatarUrl: string) => {
- setAvatarUrl(avatarUrl);
await auth.updateUser({
avatarUrl,
});
@@ -79,7 +76,7 @@ const Profile = () => {
-
-
+
+
{t("Upload")}
@@ -28,8 +29,8 @@ const avatarStyles = `
height: 64px;
`;
-const Avatar = styled.img`
- ${avatarStyles};
+const StyledAvatar = styled(Avatar)`
+ border-radius: 8px;
`;
const ImageBox = styled(Flex)`
@@ -41,7 +42,7 @@ const ImageBox = styled(Flex)`
background: ${(props) => props.theme.background};
overflow: hidden;
- div div {
+ .upload {
${avatarStyles};
position: absolute;
top: 0;
@@ -53,7 +54,7 @@ const ImageBox = styled(Flex)`
transition: all 250ms;
}
- &:hover div {
+ &:hover .upload {
opacity: 1;
background: rgba(0, 0, 0, 0.75);
color: ${(props) => props.theme.white};
diff --git a/app/scenes/Settings/components/PeopleTable.tsx b/app/scenes/Settings/components/PeopleTable.tsx
index 00485fc8a7..1910725ef2 100644
--- a/app/scenes/Settings/components/PeopleTable.tsx
+++ b/app/scenes/Settings/components/PeopleTable.tsx
@@ -29,7 +29,7 @@ function PeopleTable({ canManage, ...rest }: Props) {
Cell: observer(
({ value, row }: { value: string; row: { original: User } }) => (
- {value}{" "}
+ {value}{" "}
{currentUser.id === row.original.id && `(${t("You")})`}
)
diff --git a/app/scenes/Settings/components/SharesTable.tsx b/app/scenes/Settings/components/SharesTable.tsx
index 29f551378a..8532db7167 100644
--- a/app/scenes/Settings/components/SharesTable.tsx
+++ b/app/scenes/Settings/components/SharesTable.tsx
@@ -39,7 +39,7 @@ function SharesTable({ canManage, ...rest }: Props) {
{row.original.createdBy && (
)}
diff --git a/app/scenes/Settings/components/UserListItem.tsx b/app/scenes/Settings/components/UserListItem.tsx
index 45d707cef6..c4cba3bfd4 100644
--- a/app/scenes/Settings/components/UserListItem.tsx
+++ b/app/scenes/Settings/components/UserListItem.tsx
@@ -20,7 +20,7 @@ const UserListItem = ({ user, showMenu }: Props) => {
return (
{user.name}}
- image={}
+ image={}
subtitle={
<>
{user.email ? `${user.email} · ` : undefined}
diff --git a/app/scenes/UserProfile.tsx b/app/scenes/UserProfile.tsx
index 0a5014f80d..2e95ed360e 100644
--- a/app/scenes/UserProfile.tsx
+++ b/app/scenes/UserProfile.tsx
@@ -39,7 +39,7 @@ function UserProfile(props: Props) {
-
+
{user.name}
}
diff --git a/app/stores/AuthStore.ts b/app/stores/AuthStore.ts
index c2601b4953..8cc3e3e9bf 100644
--- a/app/stores/AuthStore.ts
+++ b/app/stores/AuthStore.ts
@@ -226,14 +226,17 @@ export default class AuthStore {
preferences?: UserPreferences;
}) => {
this.isSaving = true;
+ const previousData = this.user?.toAPI();
try {
+ this.user?.updateFromJson(params);
const res = await client.post(`/users.update`, params);
invariant(res?.data, "User response not available");
- runInAction("AuthStore#updateUser", () => {
- this.addPolicies(res.policies);
- this.user = new User(res.data, this);
- });
+ this.user?.updateFromJson(res.data);
+ this.addPolicies(res.policies);
+ } catch (err) {
+ this.user?.updateFromJson(previousData);
+ throw err;
} finally {
this.isSaving = false;
}
@@ -251,14 +254,17 @@ export default class AuthStore {
preferences?: TeamPreferences;
}) => {
this.isSaving = true;
+ const previousData = this.team?.toAPI();
try {
+ this.team?.updateFromJson(params);
const res = await client.post(`/team.update`, params);
invariant(res?.data, "Team response not available");
- runInAction("AuthStore#updateTeam", () => {
- this.addPolicies(res.policies);
- this.team = new Team(res.data, this);
- });
+ this.team?.updateFromJson(res.data);
+ this.addPolicies(res.policies);
+ } catch (err) {
+ this.team?.updateFromJson(previousData);
+ throw err;
} finally {
this.isSaving = false;
}
diff --git a/server/commands/teamCreator.ts b/server/commands/teamCreator.ts
index a5e6e7b484..c0b3a89cbf 100644
--- a/server/commands/teamCreator.ts
+++ b/server/commands/teamCreator.ts
@@ -40,7 +40,6 @@ async function teamCreator({
// one via ClearBit, or fallback to colored initials in worst case scenario
if (!avatarUrl || !avatarUrl.startsWith("http")) {
avatarUrl = await generateAvatarUrl({
- name,
domain,
id: subdomain,
});
diff --git a/server/env.ts b/server/env.ts
index 1d17631947..673967b9e8 100644
--- a/server/env.ts
+++ b/server/env.ts
@@ -329,13 +329,6 @@ export class Environment {
*/
public RELEASE = this.toOptionalString(process.env.RELEASE);
- /**
- * An optional host from which to load default avatars.
- */
- @IsUrl()
- public DEFAULT_AVATAR_HOST =
- process.env.DEFAULT_AVATAR_HOST ?? "https://tiley.herokuapp.com";
-
/**
* A Google Analytics tracking ID, only v3 supported at this time.
*/
diff --git a/server/models/Team.ts b/server/models/Team.ts
index 3bbd86ed04..dc76684234 100644
--- a/server/models/Team.ts
+++ b/server/models/Team.ts
@@ -24,7 +24,6 @@ import { CollectionPermission, TeamPreference } from "@shared/types";
import { getBaseDomain, RESERVED_SUBDOMAINS } from "@shared/utils/domains";
import env from "@server/env";
import DeleteAttachmentTask from "@server/queues/tasks/DeleteAttachmentTask";
-import { generateAvatarUrl } from "@server/utils/avatars";
import parseAttachmentIds from "@server/utils/parseAttachmentIds";
import Attachment from "./Attachment";
import AuthenticationProvider from "./AuthenticationProvider";
@@ -94,8 +93,20 @@ class Team extends ParanoidModel {
@AllowNull
@IsUrl
@Length({ max: 4096, msg: "avatarUrl must be 4096 characters or less" })
- @Column
- avatarUrl: string | null;
+ @Column(DataType.STRING)
+ get avatarUrl() {
+ const original = this.getDataValue("avatarUrl");
+
+ if (original && !original.startsWith("https://tiley.herokuapp.com")) {
+ return original;
+ }
+
+ return null;
+ }
+
+ set avatarUrl(value: string | null) {
+ this.setDataValue("avatarUrl", value);
+ }
@Default(true)
@Column
@@ -163,16 +174,6 @@ class Team extends ParanoidModel {
return url.href.replace(/\/$/, "");
}
- get logoUrl() {
- return (
- this.avatarUrl ||
- generateAvatarUrl({
- id: this.id,
- name: this.name,
- })
- );
- }
-
/**
* Preferences that decide behavior for the team.
*
diff --git a/server/models/User.ts b/server/models/User.ts
index 1cf03eb471..76ca484289 100644
--- a/server/models/User.ts
+++ b/server/models/User.ts
@@ -180,17 +180,11 @@ class User extends ParanoidModel {
get avatarUrl() {
const original = this.getDataValue("avatarUrl");
- if (original) {
+ if (original && !original.startsWith("https://tiley.herokuapp.com")) {
return original;
}
- const color = this.color.replace(/^#/, "");
- const initial = this.name ? this.name[0] : "?";
- const hash = crypto
- .createHash("md5")
- .update(this.email || "")
- .digest("hex");
- return `${env.DEFAULT_AVATAR_HOST}/avatar/${hash}/${initial}.png?c=${color}`;
+ return null;
}
set avatarUrl(value: string | null) {
diff --git a/server/presenters/__snapshots__/user.test.ts.snap b/server/presenters/__snapshots__/user.test.ts.snap
index 05e431ffdf..808d3d6306 100644
--- a/server/presenters/__snapshots__/user.test.ts.snap
+++ b/server/presenters/__snapshots__/user.test.ts.snap
@@ -2,7 +2,7 @@
exports[`presents a user 1`] = `
Object {
- "avatarUrl": "https://tiley.herokuapp.com/avatar/d41d8cd98f00b204e9800998ecf8427e/T.png?c=FF5C80",
+ "avatarUrl": null,
"color": "#FF5C80",
"createdAt": undefined,
"id": "123",
@@ -17,7 +17,7 @@ Object {
exports[`presents a user without slack data 1`] = `
Object {
- "avatarUrl": "https://tiley.herokuapp.com/avatar/d41d8cd98f00b204e9800998ecf8427e/T.png?c=FF5C80",
+ "avatarUrl": null,
"color": "#FF5C80",
"createdAt": undefined,
"id": "123",
diff --git a/server/presenters/availableTeam.ts b/server/presenters/availableTeam.ts
index 175345800b..1b0f1274d2 100644
--- a/server/presenters/availableTeam.ts
+++ b/server/presenters/availableTeam.ts
@@ -4,7 +4,7 @@ export default function present(team: Team, isSignedIn = false) {
return {
id: team.id,
name: team.name,
- avatarUrl: team.logoUrl,
+ avatarUrl: team.avatarUrl,
url: team.url,
isSignedIn,
};
diff --git a/server/presenters/team.ts b/server/presenters/team.ts
index 74748dd475..1420828106 100644
--- a/server/presenters/team.ts
+++ b/server/presenters/team.ts
@@ -4,7 +4,7 @@ export default function present(team: Team) {
return {
id: team.id,
name: team.name,
- avatarUrl: team.logoUrl,
+ avatarUrl: team.avatarUrl,
sharing: team.sharing,
memberCollectionCreate: team.memberCollectionCreate,
collaborativeEditing: team.collaborativeEditing,
diff --git a/server/routes/api/__snapshots__/users.test.ts.snap b/server/routes/api/__snapshots__/users.test.ts.snap
index 9b8e275d94..f19021c13e 100644
--- a/server/routes/api/__snapshots__/users.test.ts.snap
+++ b/server/routes/api/__snapshots__/users.test.ts.snap
@@ -3,7 +3,7 @@
exports[`#users.activate should activate a suspended user 1`] = `
Object {
"data": Object {
- "avatarUrl": "https://tiley.herokuapp.com/avatar/111d68d06e2d317b5a59c2c6c5bad808/U.png?c=e600e0",
+ "avatarUrl": null,
"color": "#e600e0",
"createdAt": "2018-01-02T00:00:00.000Z",
"email": "user1@example.com",
@@ -59,7 +59,7 @@ Object {
exports[`#users.demote should demote an admin 1`] = `
Object {
"data": Object {
- "avatarUrl": "https://tiley.herokuapp.com/avatar/111d68d06e2d317b5a59c2c6c5bad808/U.png?c=e600e0",
+ "avatarUrl": null,
"color": "#e600e0",
"createdAt": "2018-01-02T00:00:00.000Z",
"email": "user1@example.com",
@@ -97,7 +97,7 @@ Object {
exports[`#users.demote should demote an admin to member 1`] = `
Object {
"data": Object {
- "avatarUrl": "https://tiley.herokuapp.com/avatar/111d68d06e2d317b5a59c2c6c5bad808/U.png?c=e600e0",
+ "avatarUrl": null,
"color": "#e600e0",
"createdAt": "2018-01-02T00:00:00.000Z",
"email": "user1@example.com",
@@ -135,7 +135,7 @@ Object {
exports[`#users.demote should demote an admin to viewer 1`] = `
Object {
"data": Object {
- "avatarUrl": "https://tiley.herokuapp.com/avatar/111d68d06e2d317b5a59c2c6c5bad808/U.png?c=e600e0",
+ "avatarUrl": null,
"color": "#e600e0",
"createdAt": "2018-01-02T00:00:00.000Z",
"email": "user1@example.com",
@@ -191,7 +191,7 @@ Object {
exports[`#users.promote should promote a new admin 1`] = `
Object {
"data": Object {
- "avatarUrl": "https://tiley.herokuapp.com/avatar/111d68d06e2d317b5a59c2c6c5bad808/U.png?c=e600e0",
+ "avatarUrl": null,
"color": "#e600e0",
"createdAt": "2018-01-02T00:00:00.000Z",
"email": "user1@example.com",
@@ -256,7 +256,7 @@ Object {
exports[`#users.suspend should suspend an user 1`] = `
Object {
"data": Object {
- "avatarUrl": "https://tiley.herokuapp.com/avatar/111d68d06e2d317b5a59c2c6c5bad808/U.png?c=e600e0",
+ "avatarUrl": null,
"color": "#e600e0",
"createdAt": "2018-01-02T00:00:00.000Z",
"email": "user1@example.com",
diff --git a/server/utils/authentication.ts b/server/utils/authentication.ts
index a2efde3a85..80bde37c7a 100644
--- a/server/utils/authentication.ts
+++ b/server/utils/authentication.ts
@@ -93,7 +93,7 @@ export async function signIn(
...existing,
[team.id]: {
name: team.name,
- logoUrl: team.logoUrl,
+ logoUrl: team.avatarUrl,
url: team.url,
},
})
diff --git a/server/utils/avatars.test.ts b/server/utils/avatars.test.ts
index 1ad196569a..9bffe6c891 100644
--- a/server/utils/avatars.test.ts
+++ b/server/utils/avatars.test.ts
@@ -4,43 +4,6 @@ it("should return clearbit url if available", async () => {
const url = await generateAvatarUrl({
id: "google",
domain: "google.com",
- name: "Google",
});
expect(url).toBe("https://logo.clearbit.com/google.com");
});
-it("should return tiley url if clearbit unavailable", async () => {
- const url = await generateAvatarUrl({
- id: "invalid",
- domain: "example.invalid",
- name: "Invalid",
- });
- expect(url).toBe(
- "https://tiley.herokuapp.com/avatar/f1234d75178d892a133a410355a5a990cf75d2f33eba25d575943d4df632f3a4/I.png"
- );
-});
-it("should return tiley url if domain not provided", async () => {
- const url = await generateAvatarUrl({
- id: "google",
- name: "Google",
- });
- expect(url).toBe(
- "https://tiley.herokuapp.com/avatar/bbdefa2950f49882f295b1285d4fa9dec45fc4144bfb07ee6acc68762d12c2e3/G.png"
- );
-});
-it("should return tiley url if name not provided", async () => {
- const url = await generateAvatarUrl({
- id: "google",
- });
- expect(url).toBe(
- "https://tiley.herokuapp.com/avatar/bbdefa2950f49882f295b1285d4fa9dec45fc4144bfb07ee6acc68762d12c2e3/U.png"
- );
-});
-it("should return tiley url with encoded name", async () => {
- const url = await generateAvatarUrl({
- id: "google",
- name: "株",
- });
- expect(url).toBe(
- "https://tiley.herokuapp.com/avatar/bbdefa2950f49882f295b1285d4fa9dec45fc4144bfb07ee6acc68762d12c2e3/%E6%A0%AA.png"
- );
-});
diff --git a/server/utils/avatars.ts b/server/utils/avatars.ts
index 826b4afb76..d3a9f9644b 100644
--- a/server/utils/avatars.ts
+++ b/server/utils/avatars.ts
@@ -1,21 +1,17 @@
import crypto from "crypto";
import fetch from "fetch-with-proxy";
-import env from "@server/env";
export async function generateAvatarUrl({
id,
domain,
- name = "Unknown",
}: {
id: string;
domain?: string;
- name?: string;
}) {
// attempt to get logo from Clearbit API. If one doesn't exist then
// fall back to using tiley to generate a placeholder logo
const hash = crypto.createHash("sha256");
hash.update(id);
- const hashedId = hash.digest("hex");
let cbResponse, cbUrl;
if (domain) {
@@ -28,8 +24,5 @@ export async function generateAvatarUrl({
}
}
- const tileyUrl = `${
- env.DEFAULT_AVATAR_HOST
- }/avatar/${hashedId}/${encodeURIComponent(name[0])}.png`;
- return cbUrl && cbResponse && cbResponse.status === 200 ? cbUrl : tileyUrl;
+ return cbUrl && cbResponse && cbResponse.status === 200 ? cbUrl : null;
}
diff --git a/server/utils/s3.ts b/server/utils/s3.ts
index 0e21b80956..fa898f861d 100644
--- a/server/utils/s3.ts
+++ b/server/utils/s3.ts
@@ -6,7 +6,6 @@ import fetch from "fetch-with-proxy";
import { compact } from "lodash";
import { useAgent } from "request-filtering-agent";
import { v4 as uuidv4 } from "uuid";
-import env from "@server/env";
import Logger from "@server/logging/Logger";
const AWS_S3_ACCELERATE_URL = process.env.AWS_S3_ACCELERATE_URL;
@@ -184,11 +183,7 @@ export const uploadToS3FromUrl = async (
acl: string
) => {
const endpoint = publicS3Endpoint(true);
- if (
- url.startsWith("/api") ||
- url.startsWith(endpoint) ||
- url.startsWith(env.DEFAULT_AVATAR_HOST)
- ) {
+ if (url.startsWith("/api") || url.startsWith(endpoint)) {
return;
}