fix: added api routes for push registration
This commit is contained in:
@@ -3548,6 +3548,47 @@ paths:
|
||||
responses:
|
||||
'204':
|
||||
description: Successfully registered push subscription
|
||||
/user/{key}/pushSubscription:
|
||||
get:
|
||||
summary: Get web push notification settings for a user
|
||||
description: |
|
||||
Returns web push notification settings for a user in a JSON object.
|
||||
tags:
|
||||
- users
|
||||
parameters:
|
||||
- in: path
|
||||
name: key
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: User web push notification settings in JSON
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
endpoint:
|
||||
type: string
|
||||
p256dh:
|
||||
type: string
|
||||
auth:
|
||||
type: string
|
||||
delete:
|
||||
summary: Delete user push subscription by key
|
||||
description: Deletes the user push subscription with the provided key.
|
||||
tags:
|
||||
- users
|
||||
parameters:
|
||||
- in: path
|
||||
name: key
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'204':
|
||||
description: Successfully removed user push subscription
|
||||
/user/{userId}:
|
||||
get:
|
||||
summary: Get user by ID
|
||||
|
||||
@@ -138,6 +138,25 @@ router.post(
|
||||
}
|
||||
);
|
||||
|
||||
router.get<{ key: string }>(
|
||||
'/:key/pushSubscription',
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
const userPushSubRepository = getRepository(UserPushSubscription);
|
||||
|
||||
const userPushSub = await userPushSubRepository.findOneOrFail({
|
||||
where: {
|
||||
p256dh: req.params.key,
|
||||
},
|
||||
});
|
||||
|
||||
return res.status(200).json(userPushSub);
|
||||
} catch (e) {
|
||||
next({ status: 404, message: 'User subscription not found.' });
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
router.post<
|
||||
never,
|
||||
unknown,
|
||||
@@ -180,6 +199,32 @@ router.post<
|
||||
}
|
||||
});
|
||||
|
||||
router.delete<{ key: string }>(
|
||||
'/:key/pushSubscription',
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
const userPushSubRepository = getRepository(UserPushSubscription);
|
||||
|
||||
const userPushSub = await userPushSubRepository.findOneOrFail({
|
||||
where: { p256dh: req.params.key },
|
||||
});
|
||||
|
||||
await userPushSubRepository.remove(userPushSub);
|
||||
return res.status(204).send();
|
||||
} catch (e) {
|
||||
logger.error('Something went wrong deleting the user push subcription', {
|
||||
label: 'API',
|
||||
key: req.params.key,
|
||||
errorMessage: e.message,
|
||||
});
|
||||
return next({
|
||||
status: 500,
|
||||
message: 'User push subcription not found',
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
router.get<{ id: string }>('/:id', async (req, res, next) => {
|
||||
try {
|
||||
const userRepository = getRepository(User);
|
||||
|
||||
@@ -39,10 +39,33 @@ const UserDropdown = () => {
|
||||
const { user, revalidate } = useUser();
|
||||
|
||||
const logout = async () => {
|
||||
const response = await axios.post('/api/v1/auth/logout');
|
||||
if ('serviceWorker' in navigator && user?.id) {
|
||||
navigator.serviceWorker.getRegistration('/sw.js').then((registration) => {
|
||||
registration?.pushManager
|
||||
.getSubscription()
|
||||
.then(async (subscription) => {
|
||||
subscription
|
||||
?.unsubscribe()
|
||||
.then(async () => {
|
||||
const parsedSub = JSON.parse(JSON.stringify(subscription));
|
||||
await axios.delete(
|
||||
`/api/v1/user/${parsedSub.keys.p256dh}/pushSubscription`
|
||||
);
|
||||
const response = await axios.post('/api/v1/auth/logout');
|
||||
|
||||
if (response.data?.status === 'ok') {
|
||||
revalidate();
|
||||
if (response.data?.status === 'ok') {
|
||||
revalidate();
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(
|
||||
'[SW] Failure unsubscribing to push manager, error:',
|
||||
error
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
CloudArrowDownIcon,
|
||||
CloudArrowUpIcon,
|
||||
} from '@heroicons/react/24/solid';
|
||||
import type { UserPushSubscription } from '@server/entity/UserPushSubscription';
|
||||
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
|
||||
import axios from 'axios';
|
||||
import { Form, Formik } from 'formik';
|
||||
@@ -49,11 +50,6 @@ const UserWebPushSettings = () => {
|
||||
navigator.serviceWorker
|
||||
.getRegistration('/sw.js')
|
||||
.then(async (registration) => {
|
||||
const permissionState =
|
||||
await registration?.pushManager.permissionState({
|
||||
userVisibleOnly: true,
|
||||
});
|
||||
|
||||
if (currentSettings.enablePushRegistration) {
|
||||
const sub = await registration?.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
@@ -63,13 +59,11 @@ const UserWebPushSettings = () => {
|
||||
const parsedSub = JSON.parse(JSON.stringify(sub));
|
||||
|
||||
if (parsedSub.keys.p256dh && parsedSub.keys.auth) {
|
||||
if (permissionState === 'prompt') {
|
||||
await axios.post('/api/v1/user/registerPushSubscription', {
|
||||
endpoint: parsedSub.endpoint,
|
||||
p256dh: parsedSub.keys.p256dh,
|
||||
auth: parsedSub.keys.auth,
|
||||
});
|
||||
}
|
||||
await axios.post('/api/v1/user/registerPushSubscription', {
|
||||
endpoint: parsedSub.endpoint,
|
||||
p256dh: parsedSub.keys.p256dh,
|
||||
auth: parsedSub.keys.auth,
|
||||
});
|
||||
setWebPushEnabled(true);
|
||||
}
|
||||
}
|
||||
@@ -93,7 +87,13 @@ const UserWebPushSettings = () => {
|
||||
.then(async (subscription) => {
|
||||
subscription
|
||||
?.unsubscribe()
|
||||
.then(() => setWebPushEnabled(false))
|
||||
.then(async () => {
|
||||
const parsedSub = JSON.parse(JSON.stringify(subscription));
|
||||
await axios.delete(
|
||||
`/api/v1/user/${parsedSub.keys.p256dh}/pushSubscription`
|
||||
);
|
||||
setWebPushEnabled(false);
|
||||
})
|
||||
.catch(function (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(
|
||||
@@ -113,11 +113,22 @@ const UserWebPushSettings = () => {
|
||||
navigator.serviceWorker
|
||||
.getRegistration('/sw.js')
|
||||
.then(async (registration) => {
|
||||
await registration?.pushManager.getSubscription().then((status) => {
|
||||
if (status) {
|
||||
setWebPushEnabled(true);
|
||||
}
|
||||
});
|
||||
await registration?.pushManager
|
||||
.getSubscription()
|
||||
.then(async (subscription) => {
|
||||
if (subscription) {
|
||||
const parsedKey = JSON.parse(JSON.stringify(subscription));
|
||||
const currentUserPushSub =
|
||||
await axios.get<UserPushSubscription>(
|
||||
`/api/v1/user/${parsedKey.keys.p256dh}/pushSubscription`
|
||||
);
|
||||
|
||||
if (currentUserPushSub.data.p256dh !== parsedKey.keys.p256dh) {
|
||||
return;
|
||||
}
|
||||
setWebPushEnabled(true);
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(function (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
@@ -198,7 +209,7 @@ const UserWebPushSettings = () => {
|
||||
<div className="flex justify-end">
|
||||
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||
<Button
|
||||
buttonType={`${webPushEnabled ? 'danger' : 'warning'}`}
|
||||
buttonType={`${webPushEnabled ? 'danger' : 'primary'}`}
|
||||
type="button"
|
||||
onClick={() =>
|
||||
webPushEnabled
|
||||
@@ -218,20 +229,22 @@ const UserWebPushSettings = () => {
|
||||
</span>
|
||||
</Button>
|
||||
</span>
|
||||
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||
<Button
|
||||
buttonType="primary"
|
||||
type="submit"
|
||||
disabled={isSubmitting || !isValid}
|
||||
>
|
||||
<ArrowDownOnSquareIcon />
|
||||
<span>
|
||||
{isSubmitting
|
||||
? intl.formatMessage(globalMessages.saving)
|
||||
: intl.formatMessage(globalMessages.save)}
|
||||
</span>
|
||||
</Button>
|
||||
</span>
|
||||
{webPushEnabled && (
|
||||
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||
<Button
|
||||
buttonType="primary"
|
||||
type="submit"
|
||||
disabled={isSubmitting || !isValid}
|
||||
>
|
||||
<ArrowDownOnSquareIcon />
|
||||
<span>
|
||||
{isSubmitting
|
||||
? intl.formatMessage(globalMessages.saving)
|
||||
: intl.formatMessage(globalMessages.save)}
|
||||
</span>
|
||||
</Button>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
|
||||
Reference in New Issue
Block a user