mirror of
https://github.com/revoltchat/revite.git
synced 2024-11-26 00:50:56 -05:00
Migrate to rAuth v1.
This commit is contained in:
parent
a4138b52b0
commit
5b422b89e3
15 changed files with 116 additions and 87 deletions
2
external/lang
vendored
2
external/lang
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 3da029dff71f5657d6fd152d3391de8f85840d95
|
Subproject commit ad350d64633ead4c636d3cf1be5597c98f4ad006
|
|
@ -120,8 +120,8 @@
|
||||||
"react-virtualized-auto-sizer": "^1.0.5",
|
"react-virtualized-auto-sizer": "^1.0.5",
|
||||||
"react-virtuoso": "^1.10.4",
|
"react-virtuoso": "^1.10.4",
|
||||||
"redux": "^4.1.0",
|
"redux": "^4.1.0",
|
||||||
"revolt-api": "0.5.2-alpha.3",
|
"revolt-api": "0.5.3-alpha.0-patch.0",
|
||||||
"revolt.js": "5.0.1-alpha.6-patch.2",
|
"revolt.js": "5.1.0-alpha.0-patch.0",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"sass": "^1.35.1",
|
"sass": "^1.35.1",
|
||||||
"shade-blend-color": "^1.0.0",
|
"shade-blend-color": "^1.0.0",
|
||||||
|
|
|
@ -39,15 +39,15 @@ export function ModifyAccountModal({ onClose, field }: Props) {
|
||||||
}) => {
|
}) => {
|
||||||
try {
|
try {
|
||||||
if (field === "email") {
|
if (field === "email") {
|
||||||
await client.req("POST", "/auth/change/email", {
|
await client.req("POST", "/auth/account/change/email", {
|
||||||
password,
|
current_password: password,
|
||||||
new_email,
|
email: new_email,
|
||||||
});
|
});
|
||||||
onClose();
|
onClose();
|
||||||
} else if (field === "password") {
|
} else if (field === "password") {
|
||||||
await client.req("POST", "/auth/change/password", {
|
await client.req("POST", "/auth/account/change/password", {
|
||||||
password,
|
current_password: password,
|
||||||
new_password,
|
password: new_password,
|
||||||
});
|
});
|
||||||
onClose();
|
onClose();
|
||||||
} else if (field === "username") {
|
} else if (field === "username") {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* eslint-disable react-hooks/rules-of-hooks */
|
/* eslint-disable react-hooks/rules-of-hooks */
|
||||||
|
import { Session } from "revolt-api/types/Auth";
|
||||||
import { Client } from "revolt.js";
|
import { Client } from "revolt.js";
|
||||||
import { Route } from "revolt.js/dist/api/routes";
|
import { Route } from "revolt.js/dist/api/routes";
|
||||||
|
|
||||||
|
@ -15,7 +16,6 @@ import { Children } from "../../types/Preact";
|
||||||
import { useIntermediate } from "../intermediate/Intermediate";
|
import { useIntermediate } from "../intermediate/Intermediate";
|
||||||
import { registerEvents, setReconnectDisallowed } from "./events";
|
import { registerEvents, setReconnectDisallowed } from "./events";
|
||||||
import { takeError } from "./util";
|
import { takeError } from "./util";
|
||||||
import { Session } from "revolt-api/types/Auth";
|
|
||||||
|
|
||||||
export enum ClientStatus {
|
export enum ClientStatus {
|
||||||
INIT,
|
INIT,
|
||||||
|
@ -29,7 +29,9 @@ export enum ClientStatus {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ClientOperations {
|
export interface ClientOperations {
|
||||||
login: (data: Route<"POST", "/auth/login">["data"]) => Promise<void>;
|
login: (
|
||||||
|
data: Route<"POST", "/auth/session/login">["data"],
|
||||||
|
) => Promise<void>;
|
||||||
logout: (shouldRequest?: boolean) => Promise<void>;
|
logout: (shouldRequest?: boolean) => Promise<void>;
|
||||||
loggedIn: () => boolean;
|
loggedIn: () => boolean;
|
||||||
ready: () => boolean;
|
ready: () => boolean;
|
||||||
|
|
|
@ -9,7 +9,10 @@ export function takeError(error: any): string {
|
||||||
const type = error?.response?.data?.type;
|
const type = error?.response?.data?.type;
|
||||||
const id = type;
|
const id = type;
|
||||||
if (!type) {
|
if (!type) {
|
||||||
if (error?.response?.status === 403) {
|
if (
|
||||||
|
error?.response?.status === 401 ||
|
||||||
|
error?.response?.status === 403
|
||||||
|
) {
|
||||||
return "Unauthorized";
|
return "Unauthorized";
|
||||||
} else if (error && !!error.isAxiosError && !error.response) {
|
} else if (error && !!error.isAxiosError && !error.response) {
|
||||||
return "NetworkError";
|
return "NetworkError";
|
||||||
|
|
3
src/env.d.ts
vendored
3
src/env.d.ts
vendored
|
@ -1,8 +1,9 @@
|
||||||
interface ImportMetaEnv {
|
interface ImportMetaEnv {
|
||||||
|
DEV: boolean;
|
||||||
VITE_API_URL: string;
|
VITE_API_URL: string;
|
||||||
VITE_THEMES_URL: string;
|
VITE_THEMES_URL: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ImportMeta {
|
interface ImportMeta {
|
||||||
env: ImportMetaEnv
|
env: ImportMetaEnv;
|
||||||
}
|
}
|
|
@ -16,8 +16,8 @@ import { APP_VERSION } from "../../version";
|
||||||
import background from "./background.jpg";
|
import background from "./background.jpg";
|
||||||
import { FormCreate } from "./forms/FormCreate";
|
import { FormCreate } from "./forms/FormCreate";
|
||||||
import { FormLogin } from "./forms/FormLogin";
|
import { FormLogin } from "./forms/FormLogin";
|
||||||
import { FormResend } from "./forms/FormResend";
|
|
||||||
import { FormReset, FormSendReset } from "./forms/FormReset";
|
import { FormReset, FormSendReset } from "./forms/FormReset";
|
||||||
|
import { FormResend, FormVerify } from "./forms/FormVerify";
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
const theme = useContext(ThemeContext);
|
const theme = useContext(ThemeContext);
|
||||||
|
@ -52,6 +52,9 @@ export default function Login() {
|
||||||
<Route path="/login/resend">
|
<Route path="/login/resend">
|
||||||
<FormResend />
|
<FormResend />
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route path="/login/verify/:token">
|
||||||
|
<FormVerify />
|
||||||
|
</Route>
|
||||||
<Route path="/login/reset/:token">
|
<Route path="/login/reset/:token">
|
||||||
<FormReset />
|
<FormReset />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
|
@ -6,13 +6,5 @@ import { Form } from "./Form";
|
||||||
|
|
||||||
export function FormCreate() {
|
export function FormCreate() {
|
||||||
const client = useContext(AppContext);
|
const client = useContext(AppContext);
|
||||||
|
return <Form page="create" callback={(data) => client.register(data)} />;
|
||||||
return (
|
|
||||||
<Form
|
|
||||||
page="create"
|
|
||||||
callback={async (data) => {
|
|
||||||
await client.register(import.meta.env.VITE_API_URL, data);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,25 +16,25 @@ export function FormLogin() {
|
||||||
page="login"
|
page="login"
|
||||||
callback={async (data) => {
|
callback={async (data) => {
|
||||||
const browser = detect();
|
const browser = detect();
|
||||||
let device_name;
|
let friendly_name;
|
||||||
if (browser) {
|
if (browser) {
|
||||||
let { name } = browser;
|
let { name } = browser;
|
||||||
const { os } = browser;
|
const { os } = browser;
|
||||||
if (window.isNative) {
|
if (window.isNative) {
|
||||||
device_name = `Revolt Desktop on ${os}`;
|
friendly_name = `Revolt Desktop on ${os}`;
|
||||||
} else {
|
} else {
|
||||||
if (name === "ios") {
|
if (name === "ios") {
|
||||||
name = "safari";
|
name = "safari";
|
||||||
} else if (name === "fxios") {
|
} else if (name === "fxios") {
|
||||||
name = "firefox";
|
name = "firefox";
|
||||||
}
|
}
|
||||||
device_name = `${name} on ${os}`;
|
friendly_name = `${name} on ${os}`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
device_name = "Unknown Device";
|
friendly_name = "Unknown Device";
|
||||||
}
|
}
|
||||||
|
|
||||||
await login({ ...data, device_name });
|
await login({ ...data, friendly_name });
|
||||||
history.push("/");
|
history.push("/");
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
import { useContext } from "preact/hooks";
|
|
||||||
|
|
||||||
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
|
||||||
|
|
||||||
import { Form } from "./Form";
|
|
||||||
|
|
||||||
export function FormResend() {
|
|
||||||
const client = useContext(AppContext);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form
|
|
||||||
page="resend"
|
|
||||||
callback={async (data) => {
|
|
||||||
await client.req("POST", "/auth/resend", data);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -13,7 +13,7 @@ export function FormSendReset() {
|
||||||
<Form
|
<Form
|
||||||
page="send_reset"
|
page="send_reset"
|
||||||
callback={async (data) => {
|
callback={async (data) => {
|
||||||
await client.req("POST", "/auth/send_reset", data);
|
await client.req("POST", "/auth/account/reset_password", data);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -28,7 +28,7 @@ export function FormReset() {
|
||||||
<Form
|
<Form
|
||||||
page="reset"
|
page="reset"
|
||||||
callback={async (data) => {
|
callback={async (data) => {
|
||||||
await client.req("POST", "/auth/reset", {
|
await client.req("PATCH", "/auth/account/reset_password", {
|
||||||
token,
|
token,
|
||||||
...data,
|
...data,
|
||||||
});
|
});
|
||||||
|
|
48
src/pages/login/forms/FormVerify.tsx
Normal file
48
src/pages/login/forms/FormVerify.tsx
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import { useHistory, useParams } from "react-router-dom";
|
||||||
|
|
||||||
|
import { useContext, useEffect, useState } from "preact/hooks";
|
||||||
|
|
||||||
|
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||||
|
import { takeError } from "../../../context/revoltjs/util";
|
||||||
|
|
||||||
|
import Overline from "../../../components/ui/Overline";
|
||||||
|
import Preloader from "../../../components/ui/Preloader";
|
||||||
|
|
||||||
|
import { Form } from "./Form";
|
||||||
|
|
||||||
|
export function FormResend() {
|
||||||
|
const client = useContext(AppContext);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form
|
||||||
|
page="resend"
|
||||||
|
callback={async (data) => {
|
||||||
|
await client.req("POST", "/auth/account/reverify", data);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function FormVerify() {
|
||||||
|
const [error, setError] = useState<undefined | string>(undefined);
|
||||||
|
const { token } = useParams<{ token: string }>();
|
||||||
|
const client = useContext(AppContext);
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
client
|
||||||
|
.req(
|
||||||
|
"POST",
|
||||||
|
`/auth/account/verify/${token}` as "/auth/account/verify/:code",
|
||||||
|
)
|
||||||
|
.then(() => history.push("/login"))
|
||||||
|
.catch((err) => setError(takeError(err)));
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return error ? (
|
||||||
|
<Overline type="error" error={error} />
|
||||||
|
) : (
|
||||||
|
<Preloader type="ring" />
|
||||||
|
);
|
||||||
|
}
|
|
@ -46,7 +46,7 @@ export const Account = observer(() => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (email === "..." && status === ClientStatus.ONLINE) {
|
if (email === "..." && status === ClientStatus.ONLINE) {
|
||||||
client
|
client
|
||||||
.req("GET", "/auth/user")
|
.req("GET", "/auth/account")
|
||||||
.then((account) => setEmail(account.email));
|
.then((account) => setEmail(account.email));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
} from "@styled-icons/simple-icons";
|
} from "@styled-icons/simple-icons";
|
||||||
import relativeTime from "dayjs/plugin/relativeTime";
|
import relativeTime from "dayjs/plugin/relativeTime";
|
||||||
import { useHistory } from "react-router-dom";
|
import { useHistory } from "react-router-dom";
|
||||||
|
import { SessionInfo } from "revolt-api/types/Auth";
|
||||||
import { decodeTime } from "ulid";
|
import { decodeTime } from "ulid";
|
||||||
|
|
||||||
import styles from "./Panes.module.scss";
|
import styles from "./Panes.module.scss";
|
||||||
|
@ -26,17 +27,14 @@ import Tip from "../../../components/ui/Tip";
|
||||||
|
|
||||||
dayjs.extend(relativeTime);
|
dayjs.extend(relativeTime);
|
||||||
|
|
||||||
interface Session {
|
|
||||||
id: string;
|
|
||||||
friendly_name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Sessions() {
|
export function Sessions() {
|
||||||
const client = useContext(AppContext);
|
const client = useContext(AppContext);
|
||||||
const deviceId =
|
const deviceId =
|
||||||
typeof client.session === "object" ? client.session.id : undefined;
|
typeof client.session === "object" ? client.session._id : undefined;
|
||||||
|
|
||||||
const [sessions, setSessions] = useState<Session[] | undefined>(undefined);
|
const [sessions, setSessions] = useState<SessionInfo[] | undefined>(
|
||||||
|
undefined,
|
||||||
|
);
|
||||||
const [attemptingDelete, setDelete] = useState<string[]>([]);
|
const [attemptingDelete, setDelete] = useState<string[]>([]);
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
|
@ -45,10 +43,10 @@ export function Sessions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
client.req("GET", "/auth/sessions").then((data) => {
|
client.req("GET", "/auth/session/all").then((data) => {
|
||||||
data.sort(
|
data.sort(
|
||||||
(a, b) =>
|
(a, b) =>
|
||||||
(b.id === deviceId ? 1 : 0) - (a.id === deviceId ? 1 : 0),
|
(b._id === deviceId ? 1 : 0) - (a._id === deviceId ? 1 : 0),
|
||||||
);
|
);
|
||||||
setSessions(data);
|
setSessions(data);
|
||||||
});
|
});
|
||||||
|
@ -62,8 +60,8 @@ export function Sessions() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getIcon(session: Session) {
|
function getIcon(session: SessionInfo) {
|
||||||
const name = session.friendly_name;
|
const name = session.name;
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case /firefox/i.test(name):
|
case /firefox/i.test(name):
|
||||||
return <Firefoxbrowser size={32} />;
|
return <Firefoxbrowser size={32} />;
|
||||||
|
@ -84,8 +82,8 @@ export function Sessions() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSystemIcon(session: Session) {
|
function getSystemIcon(session: SessionInfo) {
|
||||||
const name = session.friendly_name;
|
const name = session.name;
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case /linux/i.test(name):
|
case /linux/i.test(name):
|
||||||
return <Linux size={14} />;
|
return <Linux size={14} />;
|
||||||
|
@ -105,12 +103,12 @@ export function Sessions() {
|
||||||
const mapped = sessions.map((session) => {
|
const mapped = sessions.map((session) => {
|
||||||
return {
|
return {
|
||||||
...session,
|
...session,
|
||||||
timestamp: decodeTime(session.id),
|
timestamp: decodeTime(session._id),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
mapped.sort((a, b) => b.timestamp - a.timestamp);
|
mapped.sort((a, b) => b.timestamp - a.timestamp);
|
||||||
const id = mapped.findIndex((x) => x.id === deviceId);
|
const id = mapped.findIndex((x) => x._id === deviceId);
|
||||||
|
|
||||||
const render = [
|
const render = [
|
||||||
mapped[id],
|
mapped[id],
|
||||||
|
@ -127,13 +125,13 @@ export function Sessions() {
|
||||||
const systemIcon = getSystemIcon(session);
|
const systemIcon = getSystemIcon(session);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={session.id}
|
key={session._id}
|
||||||
className={styles.entry}
|
className={styles.entry}
|
||||||
data-active={session.id === deviceId}
|
data-active={session._id === deviceId}
|
||||||
data-deleting={
|
data-deleting={
|
||||||
attemptingDelete.indexOf(session.id) > -1
|
attemptingDelete.indexOf(session._id) > -1
|
||||||
}>
|
}>
|
||||||
{deviceId === session.id && (
|
{deviceId === session._id && (
|
||||||
<span className={styles.label}>
|
<span className={styles.label}>
|
||||||
<Text id="app.settings.pages.sessions.this_device" />{" "}
|
<Text id="app.settings.pages.sessions.this_device" />{" "}
|
||||||
</span>
|
</span>
|
||||||
|
@ -165,7 +163,7 @@ export function Sessions() {
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className={styles.name}
|
className={styles.name}
|
||||||
value={session.friendly_name}
|
value={session.name}
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
style={{ pointerEvents: "none" }}
|
style={{ pointerEvents: "none" }}
|
||||||
/>
|
/>
|
||||||
|
@ -181,25 +179,25 @@ export function Sessions() {
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{deviceId !== session.id && (
|
{deviceId !== session._id && (
|
||||||
<Button
|
<Button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setDelete([
|
setDelete([
|
||||||
...attemptingDelete,
|
...attemptingDelete,
|
||||||
session.id,
|
session._id,
|
||||||
]);
|
]);
|
||||||
await client.req(
|
await client.req(
|
||||||
"DELETE",
|
"DELETE",
|
||||||
`/auth/sessions/${session.id}` as "/auth/sessions",
|
`/auth/session/${session._id}` as "/auth/session/id",
|
||||||
);
|
);
|
||||||
setSessions(
|
setSessions(
|
||||||
sessions?.filter(
|
sessions?.filter(
|
||||||
(x) => x.id !== session.id,
|
(x) => x._id !== session._id,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
disabled={
|
disabled={
|
||||||
attemptingDelete.indexOf(session.id) >
|
attemptingDelete.indexOf(session._id) >
|
||||||
-1
|
-1
|
||||||
}>
|
}>
|
||||||
<Text id="app.settings.pages.logOut" />
|
<Text id="app.settings.pages.logOut" />
|
||||||
|
@ -215,8 +213,8 @@ export function Sessions() {
|
||||||
// ! FIXME: add to rAuth
|
// ! FIXME: add to rAuth
|
||||||
const del: string[] = [];
|
const del: string[] = [];
|
||||||
render.forEach((session) => {
|
render.forEach((session) => {
|
||||||
if (deviceId !== session.id) {
|
if (deviceId !== session._id) {
|
||||||
del.push(session.id);
|
del.push(session._id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -225,11 +223,11 @@ export function Sessions() {
|
||||||
for (const id of del) {
|
for (const id of del) {
|
||||||
await client.req(
|
await client.req(
|
||||||
"DELETE",
|
"DELETE",
|
||||||
`/auth/sessions/${id}` as "/auth/sessions",
|
`/auth/session/${id}` as "/auth/session/id",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
setSessions(sessions.filter((x) => x.id === deviceId));
|
setSessions(sessions.filter((x) => x._id === deviceId));
|
||||||
}}>
|
}}>
|
||||||
<Text id="app.settings.pages.sessions.logout" />
|
<Text id="app.settings.pages.sessions.logout" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
16
yarn.lock
16
yarn.lock
|
@ -3654,15 +3654,15 @@ reusify@^1.0.4:
|
||||||
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
||||||
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
|
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
|
||||||
|
|
||||||
revolt-api@0.5.2-alpha.3:
|
revolt-api@0.5.3-alpha.0-patch.0:
|
||||||
version "0.5.2-alpha.3"
|
version "0.5.3-alpha.0-patch.0"
|
||||||
resolved "https://registry.yarnpkg.com/revolt-api/-/revolt-api-0.5.2-alpha.3.tgz#f980014f6cd1bef4fb3605fe56af0e829e43c6d9"
|
resolved "https://registry.yarnpkg.com/revolt-api/-/revolt-api-0.5.3-alpha.0-patch.0.tgz#158556832843bb06cb06a4df50ffca24ab64be3b"
|
||||||
integrity sha512-eIjJtUGkm83mbm1i6OxhWav2m/Xf9FJAFEA2e8YhpC1kd8vXwm/mWbPbuyTX5LNxPT9EEW0Fgx+7xt9zl5lzAw==
|
integrity sha512-76l+kGyrUy6uGMSIziyAHE27r9gD97OEh5gSzb2OJRsQM55TN0NurAsfFIEiB9hUzDDlwsXchtJiqdS4UVAwQw==
|
||||||
|
|
||||||
revolt.js@5.0.1-alpha.6-patch.2:
|
revolt.js@5.1.0-alpha.0-patch.0:
|
||||||
version "5.0.1-alpha.6-patch.2"
|
version "5.1.0-alpha.0-patch.0"
|
||||||
resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-5.0.1-alpha.6-patch.2.tgz#4a9c99f9422fdadbe2ca84a012e018d827c8f2cf"
|
resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-5.1.0-alpha.0-patch.0.tgz#3d62f32d657ee1f44381018251a6682c81cf21d8"
|
||||||
integrity sha512-FfvNFS0noGjLlxsNTUaxIHREW2z7pPu0ZFayI5MUwDqDvdaKyicyZ63zmi14UGATPkCpNiJ4ufYhcLX8ArsGTg==
|
integrity sha512-om61mNeVWiGc6+XFPpK2YM6i6QSOT3f5prhVyM78BcZZ5U2L39SWBN3S7ycAsr8g4Q9pPLv50qYwnsMjxe4P/A==
|
||||||
dependencies:
|
dependencies:
|
||||||
axios "^0.19.2"
|
axios "^0.19.2"
|
||||||
eventemitter3 "^4.0.7"
|
eventemitter3 "^4.0.7"
|
||||||
|
|
Loading…
Reference in a new issue