Split out AccountApi
parent
d4c7ad4beb
commit
276301dc87
|
@ -0,0 +1,205 @@
|
|||
import {
|
||||
accountPasswordUrl,
|
||||
accountSettingsUrl,
|
||||
accountSubscriptionSingleUrl,
|
||||
accountSubscriptionUrl,
|
||||
accountTokenUrl,
|
||||
accountUrl,
|
||||
fetchLinesIterator,
|
||||
maybeWithBasicAuth,
|
||||
maybeWithBearerAuth,
|
||||
topicShortUrl,
|
||||
topicUrl,
|
||||
topicUrlAuth,
|
||||
topicUrlJsonPoll,
|
||||
topicUrlJsonPollWithSince
|
||||
} from "./utils";
|
||||
import userManager from "./UserManager";
|
||||
import session from "./Session";
|
||||
|
||||
class AccountApi {
|
||||
async login(user) {
|
||||
const url = accountTokenUrl(config.baseUrl);
|
||||
console.log(`[Api] Checking auth for ${url}`);
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: maybeWithBasicAuth({}, user)
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
const json = await response.json();
|
||||
if (!json.token) {
|
||||
throw new Error(`Unexpected server response: Cannot find token`);
|
||||
}
|
||||
return json.token;
|
||||
}
|
||||
|
||||
async logout(token) {
|
||||
const url = accountTokenUrl(config.baseUrl);
|
||||
console.log(`[Api] Logging out from ${url} using token ${token}`);
|
||||
const response = await fetch(url, {
|
||||
method: "DELETE",
|
||||
headers: maybeWithBearerAuth({}, token)
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
async create(username, password) {
|
||||
const url = accountUrl(config.baseUrl);
|
||||
const body = JSON.stringify({
|
||||
username: username,
|
||||
password: password
|
||||
});
|
||||
console.log(`[Api] Creating user account ${url}`);
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
body: body
|
||||
});
|
||||
if (response.status === 409) {
|
||||
throw new UsernameTakenError(username);
|
||||
} else if (response.status === 429) {
|
||||
throw new AccountCreateLimitReachedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
async get() {
|
||||
const url = accountUrl(config.baseUrl);
|
||||
console.log(`[Api] Fetching user account ${url}`);
|
||||
const response = await fetch(url, {
|
||||
headers: maybeWithBearerAuth({}, session.token())
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
const account = await response.json();
|
||||
console.log(`[Api] Account`, account);
|
||||
return account;
|
||||
}
|
||||
|
||||
async delete() {
|
||||
const url = accountUrl(config.baseUrl);
|
||||
console.log(`[Api] Deleting user account ${url}`);
|
||||
const response = await fetch(url, {
|
||||
method: "DELETE",
|
||||
headers: maybeWithBearerAuth({}, session.token())
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
async changePassword(newPassword) {
|
||||
const url = accountPasswordUrl(config.baseUrl);
|
||||
console.log(`[Api] Changing account password ${url}`);
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: maybeWithBearerAuth({}, session.token()),
|
||||
body: JSON.stringify({
|
||||
password: newPassword
|
||||
})
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
async extendToken() {
|
||||
const url = accountTokenUrl(config.baseUrl);
|
||||
console.log(`[Api] Extending user access token ${url}`);
|
||||
const response = await fetch(url, {
|
||||
method: "PATCH",
|
||||
headers: maybeWithBearerAuth({}, session.token())
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
async updateSettings(payload) {
|
||||
const url = accountSettingsUrl(config.baseUrl);
|
||||
const body = JSON.stringify(payload);
|
||||
console.log(`[Api] Updating user account ${url}: ${body}`);
|
||||
const response = await fetch(url, {
|
||||
method: "PATCH",
|
||||
headers: maybeWithBearerAuth({}, session.token()),
|
||||
body: body
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
async addSubscription(payload) {
|
||||
const url = accountSubscriptionUrl(config.baseUrl);
|
||||
const body = JSON.stringify(payload);
|
||||
console.log(`[Api] Adding user subscription ${url}: ${body}`);
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: maybeWithBearerAuth({}, session.token()),
|
||||
body: body
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
const subscription = await response.json();
|
||||
console.log(`[Api] Subscription`, subscription);
|
||||
return subscription;
|
||||
}
|
||||
|
||||
async deleteSubscription(remoteId) {
|
||||
const url = accountSubscriptionSingleUrl(config.baseUrl, remoteId);
|
||||
console.log(`[Api] Removing user subscription ${url}`);
|
||||
const response = await fetch(url, {
|
||||
method: "DELETE",
|
||||
headers: maybeWithBearerAuth({}, session.token())
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class UsernameTakenError extends Error {
|
||||
constructor(username) {
|
||||
super("Username taken");
|
||||
this.username = username;
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountCreateLimitReachedError extends Error {
|
||||
constructor() {
|
||||
super("Account creation limit reached");
|
||||
}
|
||||
}
|
||||
|
||||
export class UnauthorizedError extends Error {
|
||||
constructor() {
|
||||
super("Unauthorized");
|
||||
}
|
||||
}
|
||||
|
||||
const accountApi = new AccountApi();
|
||||
export default accountApi;
|
|
@ -122,188 +122,6 @@ class Api {
|
|||
}
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
|
||||
async login(baseUrl, user) {
|
||||
const url = accountTokenUrl(baseUrl);
|
||||
console.log(`[Api] Checking auth for ${url}`);
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: maybeWithBasicAuth({}, user)
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
const json = await response.json();
|
||||
if (!json.token) {
|
||||
throw new Error(`Unexpected server response: Cannot find token`);
|
||||
}
|
||||
return json.token;
|
||||
}
|
||||
|
||||
async logout(baseUrl, token) {
|
||||
const url = accountTokenUrl(baseUrl);
|
||||
console.log(`[Api] Logging out from ${url} using token ${token}`);
|
||||
const response = await fetch(url, {
|
||||
method: "DELETE",
|
||||
headers: maybeWithBearerAuth({}, token)
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
async createAccount(baseUrl, username, password) {
|
||||
const url = accountUrl(baseUrl);
|
||||
const body = JSON.stringify({
|
||||
username: username,
|
||||
password: password
|
||||
});
|
||||
console.log(`[Api] Creating user account ${url}`);
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
body: body
|
||||
});
|
||||
if (response.status === 409) {
|
||||
throw new UsernameTakenError(username);
|
||||
} else if (response.status === 429) {
|
||||
throw new AccountCreateLimitReachedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
async getAccount(baseUrl, token) {
|
||||
const url = accountUrl(baseUrl);
|
||||
console.log(`[Api] Fetching user account ${url}`);
|
||||
const response = await fetch(url, {
|
||||
headers: maybeWithBearerAuth({}, token)
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
const account = await response.json();
|
||||
console.log(`[Api] Account`, account);
|
||||
return account;
|
||||
}
|
||||
|
||||
async deleteAccount(baseUrl, token) {
|
||||
const url = accountUrl(baseUrl);
|
||||
console.log(`[Api] Deleting user account ${url}`);
|
||||
const response = await fetch(url, {
|
||||
method: "DELETE",
|
||||
headers: maybeWithBearerAuth({}, token)
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
async changePassword(baseUrl, token, password) {
|
||||
const url = accountPasswordUrl(baseUrl);
|
||||
console.log(`[Api] Changing account password ${url}`);
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: maybeWithBearerAuth({}, token),
|
||||
body: JSON.stringify({
|
||||
password: password
|
||||
})
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
async extendToken(baseUrl, token) {
|
||||
const url = accountTokenUrl(baseUrl);
|
||||
console.log(`[Api] Extending user access token ${url}`);
|
||||
const response = await fetch(url, {
|
||||
method: "PATCH",
|
||||
headers: maybeWithBearerAuth({}, token)
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
async updateAccountSettings(baseUrl, token, payload) {
|
||||
const url = accountSettingsUrl(baseUrl);
|
||||
const body = JSON.stringify(payload);
|
||||
console.log(`[Api] Updating user account ${url}: ${body}`);
|
||||
const response = await fetch(url, {
|
||||
method: "PATCH",
|
||||
headers: maybeWithBearerAuth({}, token),
|
||||
body: body
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
async addAccountSubscription(baseUrl, token, payload) {
|
||||
const url = accountSubscriptionUrl(baseUrl);
|
||||
const body = JSON.stringify(payload);
|
||||
console.log(`[Api] Adding user subscription ${url}: ${body}`);
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: maybeWithBearerAuth({}, token),
|
||||
body: body
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
const subscription = await response.json();
|
||||
console.log(`[Api] Subscription`, subscription);
|
||||
return subscription;
|
||||
}
|
||||
|
||||
async deleteAccountSubscription(baseUrl, token, remoteId) {
|
||||
const url = accountSubscriptionSingleUrl(baseUrl, remoteId);
|
||||
console.log(`[Api] Removing user subscription ${url}`);
|
||||
const response = await fetch(url, {
|
||||
method: "DELETE",
|
||||
headers: maybeWithBearerAuth({}, token)
|
||||
});
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new UnauthorizedError();
|
||||
} else if (response.status !== 200) {
|
||||
throw new Error(`Unexpected server response ${response.status}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class UsernameTakenError extends Error {
|
||||
constructor(username) {
|
||||
super("Username taken");
|
||||
this.username = username;
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountCreateLimitReachedError extends Error {
|
||||
constructor() {
|
||||
super("Account creation limit reached");
|
||||
}
|
||||
}
|
||||
|
||||
export class UnauthorizedError extends Error {
|
||||
constructor() {
|
||||
super("Unauthorized");
|
||||
}
|
||||
}
|
||||
|
||||
const api = new Api();
|
||||
|
|
|
@ -16,11 +16,11 @@ import DialogTitle from "@mui/material/DialogTitle";
|
|||
import DialogContent from "@mui/material/DialogContent";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import DialogActions from "@mui/material/DialogActions";
|
||||
import api, {UnauthorizedError} from "../app/Api";
|
||||
import routes from "./routes";
|
||||
import IconButton from "@mui/material/IconButton";
|
||||
import {useNavigate, useOutletContext} from "react-router-dom";
|
||||
import {useOutletContext} from "react-router-dom";
|
||||
import {formatBytes} from "../app/utils";
|
||||
import accountApi, {UnauthorizedError} from "../app/AccountApi";
|
||||
|
||||
const Account = () => {
|
||||
if (!session.exists()) {
|
||||
|
@ -147,7 +147,7 @@ const ChangePassword = () => {
|
|||
};
|
||||
const handleDialogSubmit = async (newPassword) => {
|
||||
try {
|
||||
await api.changePassword(config.baseUrl, session.token(), newPassword);
|
||||
await accountApi.changePassword(newPassword);
|
||||
setDialogOpen(false);
|
||||
console.debug(`[Account] Password changed`);
|
||||
} catch (e) {
|
||||
|
@ -234,7 +234,7 @@ const DeleteAccount = () => {
|
|||
};
|
||||
const handleDialogSubmit = async (newPassword) => {
|
||||
try {
|
||||
await api.deleteAccount(config.baseUrl, session.token());
|
||||
await accountApi.delete();
|
||||
setDialogOpen(false);
|
||||
console.debug(`[Account] Account deleted`);
|
||||
// TODO delete local storage
|
||||
|
|
|
@ -18,7 +18,7 @@ import MenuList from '@mui/material/MenuList';
|
|||
import MoreVertIcon from "@mui/icons-material/MoreVert";
|
||||
import NotificationsIcon from '@mui/icons-material/Notifications';
|
||||
import NotificationsOffIcon from '@mui/icons-material/NotificationsOff';
|
||||
import api, {UnauthorizedError} from "../app/Api";
|
||||
import api from "../app/Api";
|
||||
import routes from "./routes";
|
||||
import subscriptionManager from "../app/SubscriptionManager";
|
||||
import logo from "../img/ntfy.svg";
|
||||
|
@ -31,6 +31,7 @@ import Button from "@mui/material/Button";
|
|||
import Divider from "@mui/material/Divider";
|
||||
import {Logout, Person, Settings} from "@mui/icons-material";
|
||||
import ListItemIcon from "@mui/material/ListItemIcon";
|
||||
import accountApi, {UnauthorizedError} from "../app/AccountApi";
|
||||
|
||||
const ActionBar = (props) => {
|
||||
const { t } = useTranslation();
|
||||
|
@ -119,7 +120,7 @@ const SettingsIcons = (props) => {
|
|||
await subscriptionManager.remove(props.subscription.id);
|
||||
if (session.exists() && props.subscription.remoteId) {
|
||||
try {
|
||||
await api.deleteAccountSubscription(config.baseUrl, session.token(), props.subscription.remoteId);
|
||||
await accountApi.deleteSubscription(props.subscription.remoteId);
|
||||
} catch (e) {
|
||||
console.log(`[ActionBar] Error unsubscribing`, e);
|
||||
if ((e instanceof UnauthorizedError)) {
|
||||
|
@ -268,9 +269,12 @@ const ProfileIcon = (props) => {
|
|||
setAnchorEl(null);
|
||||
};
|
||||
const handleLogout = async () => {
|
||||
await api.logout(config.baseUrl, session.token());
|
||||
session.reset();
|
||||
window.location.href = routes.app;
|
||||
try {
|
||||
await accountApi.logout();
|
||||
} finally {
|
||||
session.reset();
|
||||
window.location.href = routes.app;
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -26,13 +26,13 @@ import {Backdrop, CircularProgress} from "@mui/material";
|
|||
import Home from "./Home";
|
||||
import Login from "./Login";
|
||||
import i18n from "i18next";
|
||||
import api, {UnauthorizedError} from "../app/Api";
|
||||
import prefs from "../app/Prefs";
|
||||
import session from "../app/Session";
|
||||
import Pricing from "./Pricing";
|
||||
import Signup from "./Signup";
|
||||
import Account from "./Account";
|
||||
import ResetPassword from "./ResetPassword";
|
||||
import accountApi, {UnauthorizedError} from "../app/AccountApi";
|
||||
|
||||
// TODO races when two tabs are open
|
||||
// TODO investigate service workers
|
||||
|
@ -101,24 +101,24 @@ const Layout = () => {
|
|||
if (!session.token()) {
|
||||
return;
|
||||
}
|
||||
const acc = await api.getAccount(config.baseUrl, session.token());
|
||||
setAccount(acc);
|
||||
if (acc.language) {
|
||||
await i18n.changeLanguage(acc.language);
|
||||
const remoteAccount = await accountApi.get();
|
||||
setAccount(remoteAccount);
|
||||
if (remoteAccount.language) {
|
||||
await i18n.changeLanguage(remoteAccount.language);
|
||||
}
|
||||
if (acc.notification) {
|
||||
if (acc.notification.sound) {
|
||||
await prefs.setSound(acc.notification.sound);
|
||||
if (remoteAccount.notification) {
|
||||
if (remoteAccount.notification.sound) {
|
||||
await prefs.setSound(remoteAccount.notification.sound);
|
||||
}
|
||||
if (acc.notification.delete_after) {
|
||||
await prefs.setDeleteAfter(acc.notification.delete_after);
|
||||
if (remoteAccount.notification.delete_after) {
|
||||
await prefs.setDeleteAfter(remoteAccount.notification.delete_after);
|
||||
}
|
||||
if (acc.notification.min_priority) {
|
||||
await prefs.setMinPriority(acc.notification.min_priority);
|
||||
if (remoteAccount.notification.min_priority) {
|
||||
await prefs.setMinPriority(remoteAccount.notification.min_priority);
|
||||
}
|
||||
}
|
||||
if (acc.subscriptions) {
|
||||
await subscriptionManager.syncFromRemote(acc.subscriptions);
|
||||
if (remoteAccount.subscriptions) {
|
||||
await subscriptionManager.syncFromRemote(remoteAccount.subscriptions);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(`[App] Error fetching account`, e);
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import * as React from 'react';
|
||||
import {useState} from 'react';
|
||||
import Typography from "@mui/material/Typography";
|
||||
import WarningAmberIcon from '@mui/icons-material/WarningAmber';
|
||||
import TextField from "@mui/material/TextField";
|
||||
import Button from "@mui/material/Button";
|
||||
import Box from "@mui/material/Box";
|
||||
import api, {UnauthorizedError} from "../app/Api";
|
||||
import routes from "./routes";
|
||||
import session from "../app/Session";
|
||||
import {NavLink} from "react-router-dom";
|
||||
import AvatarBox from "./AvatarBox";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {useState} from "react";
|
||||
import accountApi, {UnauthorizedError} from "../app/AccountApi";
|
||||
|
||||
const Login = () => {
|
||||
const { t } = useTranslation();
|
||||
|
@ -21,7 +21,7 @@ const Login = () => {
|
|||
event.preventDefault();
|
||||
const user = { username, password };
|
||||
try {
|
||||
const token = await api.login(config.baseUrl, user);
|
||||
const token = await accountApi.login(user);
|
||||
console.log(`[Login] User auth for user ${user.username} successful, token is ${token}`);
|
||||
session.store(user.username, token);
|
||||
window.location.href = routes.app;
|
||||
|
|
|
@ -34,9 +34,9 @@ import DialogActions from "@mui/material/DialogActions";
|
|||
import userManager from "../app/UserManager";
|
||||
import {playSound, shuffle, sounds, validTopic, validUrl} from "../app/utils";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import api, {UnauthorizedError} from "../app/Api";
|
||||
import session from "../app/Session";
|
||||
import routes from "./routes";
|
||||
import accountApi, {UnauthorizedError} from "../app/AccountApi";
|
||||
|
||||
const Preferences = () => {
|
||||
return (
|
||||
|
@ -668,7 +668,7 @@ const maybeUpdateAccountSettings = async (payload) => {
|
|||
return;
|
||||
}
|
||||
try {
|
||||
await api.updateAccountSettings(config.baseUrl, session.token(), payload);
|
||||
await accountApi.updateSettings(payload);
|
||||
} catch (e) {
|
||||
console.log(`[Preferences] Error updating account settings`, e);
|
||||
if ((e instanceof UnauthorizedError)) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import * as React from 'react';
|
||||
import {useEffect, useRef, useState} from 'react';
|
||||
import {NotificationItem} from "./Notifications";
|
||||
import theme from "./theme";
|
||||
import {Checkbox, Chip, FormControl, FormControlLabel, InputLabel, Link, Select, useMediaQuery} from "@mui/material";
|
||||
import TextField from "@mui/material/TextField";
|
||||
|
@ -18,16 +17,17 @@ import IconButton from "@mui/material/IconButton";
|
|||
import InsertEmoticonIcon from '@mui/icons-material/InsertEmoticon';
|
||||
import {Close} from "@mui/icons-material";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import {basicAuth, formatBytes, maybeWithBasicAuth, topicShortUrl, topicUrl, validTopic, validUrl} from "../app/utils";
|
||||
import {formatBytes, maybeWithBasicAuth, topicShortUrl, topicUrl, validTopic, validUrl} from "../app/utils";
|
||||
import Box from "@mui/material/Box";
|
||||
import AttachmentIcon from "./AttachmentIcon";
|
||||
import DialogFooter from "./DialogFooter";
|
||||
import api, {UnauthorizedError} from "../app/Api";
|
||||
import api from "../app/Api";
|
||||
import userManager from "../app/UserManager";
|
||||
import EmojiPicker from "./EmojiPicker";
|
||||
import {Trans, useTranslation} from "react-i18next";
|
||||
import session from "../app/Session";
|
||||
import routes from "./routes";
|
||||
import accountApi, {UnauthorizedError} from "../app/AccountApi";
|
||||
|
||||
const PublishDialog = (props) => {
|
||||
const { t } = useTranslation();
|
||||
|
@ -161,7 +161,7 @@ const PublishDialog = (props) => {
|
|||
|
||||
const checkAttachmentLimits = async (file) => {
|
||||
try {
|
||||
const account = await api.getAccount(baseUrl, session.token());
|
||||
const account = await accountApi.get();
|
||||
const fileSizeLimit = account.limits.attachment_file_size ?? 0;
|
||||
const remainingBytes = account.stats.attachment_total_size_remaining;
|
||||
const fileSizeLimitReached = fileSizeLimit > 0 && file.size > fileSizeLimit;
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import * as React from 'react';
|
||||
import {useState} from 'react';
|
||||
import TextField from "@mui/material/TextField";
|
||||
import Button from "@mui/material/Button";
|
||||
import Box from "@mui/material/Box";
|
||||
import api, {AccountCreateLimitReachedError, UnauthorizedError, UsernameTakenError} from "../app/Api";
|
||||
import routes from "./routes";
|
||||
import session from "../app/Session";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import {NavLink} from "react-router-dom";
|
||||
import AvatarBox from "./AvatarBox";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {useState} from "react";
|
||||
import WarningAmberIcon from "@mui/icons-material/WarningAmber";
|
||||
import accountApi, {AccountCreateLimitReachedError, UsernameTakenError} from "../app/AccountApi";
|
||||
|
||||
const Signup = () => {
|
||||
const { t } = useTranslation();
|
||||
|
@ -22,8 +22,8 @@ const Signup = () => {
|
|||
event.preventDefault();
|
||||
const user = { username, password };
|
||||
try {
|
||||
await api.createAccount(config.baseUrl, user.username, user.password);
|
||||
const token = await api.login(config.baseUrl, user);
|
||||
await accountApi.create(user.username, user.password);
|
||||
const token = await accountApi.login(user);
|
||||
console.log(`[Signup] User signup for user ${user.username} successful, token is ${token}`);
|
||||
session.store(user.username, token);
|
||||
window.location.href = routes.app;
|
||||
|
|
|
@ -8,7 +8,7 @@ import DialogContentText from '@mui/material/DialogContentText';
|
|||
import DialogTitle from '@mui/material/DialogTitle';
|
||||
import {Autocomplete, Checkbox, FormControlLabel, useMediaQuery} from "@mui/material";
|
||||
import theme from "./theme";
|
||||
import api, {UnauthorizedError} from "../app/Api";
|
||||
import api from "../app/Api";
|
||||
import {randomAlphanumericString, topicUrl, validTopic, validUrl} from "../app/utils";
|
||||
import userManager from "../app/UserManager";
|
||||
import subscriptionManager from "../app/SubscriptionManager";
|
||||
|
@ -17,6 +17,7 @@ import DialogFooter from "./DialogFooter";
|
|||
import {useTranslation} from "react-i18next";
|
||||
import session from "../app/Session";
|
||||
import routes from "./routes";
|
||||
import accountApi, {UnauthorizedError} from "../app/AccountApi";
|
||||
|
||||
const publicBaseUrl = "https://ntfy.sh";
|
||||
|
||||
|
@ -31,7 +32,7 @@ const SubscribeDialog = (props) => {
|
|||
const subscription = await subscriptionManager.add(actualBaseUrl, topic);
|
||||
if (session.exists()) {
|
||||
try {
|
||||
const remoteSubscription = await api.addAccountSubscription(config.baseUrl, session.token(), {
|
||||
const remoteSubscription = await accountApi.addSubscription({
|
||||
base_url: actualBaseUrl,
|
||||
topic: topic
|
||||
});
|
||||
|
|
|
@ -8,7 +8,8 @@ import connectionManager from "../app/ConnectionManager";
|
|||
import poller from "../app/Poller";
|
||||
import pruner from "../app/Pruner";
|
||||
import session from "../app/Session";
|
||||
import api, {UnauthorizedError} from "../app/Api";
|
||||
import {UnauthorizedError} from "../app/AccountApi";
|
||||
import accountApi from "../app/AccountApi";
|
||||
|
||||
/**
|
||||
* Wire connectionManager and subscriptionManager so that subscriptions are updated when the connection
|
||||
|
@ -65,7 +66,7 @@ export const useAutoSubscribe = (subscriptions, selected) => {
|
|||
const subscription = await subscriptionManager.add(baseUrl, params.topic);
|
||||
if (session.exists()) {
|
||||
try {
|
||||
const remoteSubscription = await api.addAccountSubscription(config.baseUrl, session.token(), {
|
||||
const remoteSubscription = await accountApi.addSubscription({
|
||||
base_url: baseUrl,
|
||||
topic: params.topic
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue