feat(web): add spaces, grouped channels and file chat
This commit is contained in:
1 parent
c7d8ef15bc
commit
f6cfb12716
111 files changed
+4371
-506
No files matched your search
@@ -0,0 +1,37 @@
|
||||
import { parseChannelLink, type ParsedChannelLink } from '@/lib/channelLink';
|
||||
import { makeLink } from './links';
|
||||
import { decryptInvitation, encryptInvitation } from './accountCrypto';
|
||||
|
||||
interface ChannelGrant {
|
||||
v: 1;
|
||||
channelId: string;
|
||||
mode: 'enc' | 'raw';
|
||||
role: 'owner' | 'member';
|
||||
keys: ParsedChannelLink['keys'];
|
||||
}
|
||||
|
||||
export async function sealChannelGrant(link: string, recipient: string, publicKey: JsonWebKey): Promise<string> {
|
||||
const parsed = parseChannelLink(link);
|
||||
if (!parsed.ok) throw new Error('空间凭据格式无效');
|
||||
const grant: ChannelGrant = { v: 1, channelId: parsed.link.id, mode: parsed.link.mode,
|
||||
role: parsed.link.isOwner ? 'owner' : 'member', keys: parsed.link.keys };
|
||||
return encryptInvitation(JSON.stringify(grant), recipient, grant.channelId, publicKey);
|
||||
}
|
||||
|
||||
export async function openChannelGrant(payload: string, recipient: string, channelId: string, privateKey: JsonWebKey,
|
||||
role: 'owner' | 'member', origin: string): Promise<ParsedChannelLink> {
|
||||
const plain = await decryptInvitation(payload, recipient, channelId, privateKey);
|
||||
let parsed: ReturnType<typeof parseChannelLink>;
|
||||
if (plain.startsWith('{')) {
|
||||
const grant = JSON.parse(plain) as ChannelGrant;
|
||||
if (grant.v !== 1 || grant.channelId !== channelId || grant.role !== role || !['enc', 'raw'].includes(grant.mode)
|
||||
|| !grant.keys || typeof grant.keys !== 'object') throw new Error('空间授权包校验失败');
|
||||
parsed = parseChannelLink(makeLink(origin, channelId, grant.keys));
|
||||
if (!parsed.ok || parsed.link.mode !== grant.mode) throw new Error('空间授权包模式不匹配');
|
||||
} else {
|
||||
// Existing invitations hold an encrypted link; their secret never becomes a navigation URL.
|
||||
parsed = parseChannelLink(plain);
|
||||
}
|
||||
if (!parsed.ok || parsed.link.id !== channelId || parsed.link.isOwner !== (role === 'owner')) throw new Error('空间授权包权限不匹配');
|
||||
return parsed.link;
|
||||
}
|
||||
Reference in new issue
Block a user