Creating replication documents when needed
This commit is contained in:
parent
b7dd6aa15a
commit
d6538843d2
|
@ -19,6 +19,8 @@ import { isFunction } from 'lodash';
|
|||
import { userId } from '~/lib/user-id';
|
||||
import { userExists } from '~/lib/user-exists';
|
||||
import { update } from '~/lib/update';
|
||||
import { replicationDocument } from '~/lib/replication-document';
|
||||
import { get } from '~/lib/get';
|
||||
|
||||
interface Props {
|
||||
values?: () => any;
|
||||
|
@ -114,6 +116,10 @@ const User: Component<Props> = (props) => {
|
|||
database,
|
||||
};
|
||||
|
||||
const currentUserId = userId(data('username'), data('database'));
|
||||
const credentials = adminCredentials();
|
||||
const adminUser = credentials?.username || '';
|
||||
|
||||
for (let i = 0; i < updatedSubscriptions.length; i++) {
|
||||
let subscription = updatedSubscriptions[i];
|
||||
if (!isIn(subscription.username, previousSubscriptions())) {
|
||||
|
@ -122,6 +128,24 @@ const User: Component<Props> = (props) => {
|
|||
addSubscriptionFactory(subscription.username),
|
||||
defaultUserDocument
|
||||
);
|
||||
const otherUserId = userId(subscription.username, data('database'));
|
||||
const otherUserPassword = (await get(otherUserId)).password;
|
||||
let repDocument = replicationDocument(
|
||||
currentUserId,
|
||||
data('password'),
|
||||
otherUserId,
|
||||
otherUserPassword,
|
||||
adminUser
|
||||
);
|
||||
await put(repDocument._id, repDocument, false, '_replicator');
|
||||
repDocument = replicationDocument(
|
||||
otherUserId,
|
||||
otherUserPassword,
|
||||
currentUserId,
|
||||
data('password'),
|
||||
adminUser
|
||||
);
|
||||
await put(repDocument._id, repDocument, false, '_replicator');
|
||||
console.log({
|
||||
caller: 'User / submitHandler / new subscription',
|
||||
username: subscription.username,
|
||||
|
@ -139,6 +163,7 @@ const User: Component<Props> = (props) => {
|
|||
removeSubscriptionFactory(subscription.username),
|
||||
defaultUserDocument
|
||||
);
|
||||
|
||||
console.log({
|
||||
caller: 'User / submitHandler / deleted subscription',
|
||||
username: subscription.username,
|
||||
|
@ -269,7 +294,7 @@ const User: Component<Props> = (props) => {
|
|||
<Progress.Root
|
||||
value={progress()}
|
||||
minValue={0}
|
||||
maxValue={10}
|
||||
maxValue={3}
|
||||
getValueLabel={({ value, max }) =>
|
||||
`${value} of ${max} tasks completed`
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
import { toHex } from './to-hex';
|
||||
|
||||
export const getDbUrlForUser = (user: { username: string; hostname: string }) =>
|
||||
`https://${user.hostname}/userdb-${toHex(user.username)}`;
|
|
@ -0,0 +1,51 @@
|
|||
import { parseUserId } from './user-id';
|
||||
import { getDbUrlForUser } from './get-db-url-for-user';
|
||||
|
||||
export const replicationDocument = (
|
||||
userFromId: string,
|
||||
userFromPassword: string,
|
||||
userToId: string,
|
||||
userToPassword: string,
|
||||
adminUser: string
|
||||
) => {
|
||||
const userFrom = parseUserId(userFromId);
|
||||
const userTo = parseUserId(userToId);
|
||||
|
||||
const document = {
|
||||
_id: `${userFromId}=>${userToId}`,
|
||||
user_ctx: {
|
||||
name: adminUser,
|
||||
roles: ['_admin', '_reader', '_writer'],
|
||||
},
|
||||
source: {
|
||||
url: getDbUrlForUser(userFrom),
|
||||
auth: {
|
||||
basic: {
|
||||
username: userFrom.username,
|
||||
password: userFromPassword,
|
||||
},
|
||||
},
|
||||
},
|
||||
target: {
|
||||
url: getDbUrlForUser(userTo),
|
||||
auth: {
|
||||
basic: {
|
||||
username: userTo.username,
|
||||
password: userToPassword,
|
||||
},
|
||||
},
|
||||
},
|
||||
selector: {
|
||||
to: {
|
||||
$elemMatch: {
|
||||
$eq: userToId,
|
||||
},
|
||||
},
|
||||
},
|
||||
create_target: false,
|
||||
continuous: true,
|
||||
owner: adminUser,
|
||||
};
|
||||
|
||||
return document;
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
import { get } from './get';
|
||||
import { put } from './put';
|
||||
|
||||
export const update = async (
|
||||
id: string,
|
||||
updater: (doc: any) => any,
|
||||
defaultDocument: any,
|
||||
db = 'dyomedea_users'
|
||||
) => {
|
||||
const previous = await get(id, db);
|
||||
|
||||
const newDocument = updater(previous || defaultDocument);
|
||||
|
||||
console.log({
|
||||
caller: 'update',
|
||||
id,
|
||||
defaultDocument,
|
||||
db,
|
||||
previous,
|
||||
newDocument,
|
||||
});
|
||||
|
||||
return await put(id, newDocument, false, db);
|
||||
};
|
|
@ -0,0 +1,30 @@
|
|||
import { adminCredentials } from '~/components/credentials';
|
||||
import { headersWithAuth } from './headers-with-auth';
|
||||
|
||||
export const userExists = async (username: string) => {
|
||||
const credentials = adminCredentials();
|
||||
if (!credentials) {
|
||||
return null;
|
||||
}
|
||||
const { database } = credentials;
|
||||
|
||||
const headers = headersWithAuth();
|
||||
if (!headers) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${database}/_users/org.couchdb.user:${username}`,
|
||||
{
|
||||
method: 'HEAD',
|
||||
mode: 'cors',
|
||||
headers,
|
||||
}
|
||||
);
|
||||
return response.status === 200;
|
||||
} catch (error) {
|
||||
console.error({ caller: 'userExists', error });
|
||||
return null;
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue