allow server to require new channels be sealed

This commit is contained in:
root 2023-12-22 07:16:24 -08:00
parent a4deb48bba
commit 61d2660f88
13 changed files with 51 additions and 14 deletions

View File

@ -3895,6 +3895,8 @@ components:
type: string type: string
pushSupported: pushSupported:
type: boolean type: boolean
allowUnsealed:
type: boolean
enableIce: enableIce:
type: boolean type: boolean
iceUrl: iceUrl:
@ -4289,6 +4291,8 @@ components:
updated: updated:
type: integer type: integer
format: int64 format: int64
allowUnsealed:
type: boolean
enableImage: enableImage:
type: boolean type: boolean
enableAudio: enableAudio:

View File

@ -33,8 +33,8 @@ RUN n stable
RUN mkdir /app RUN mkdir /app
RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then ARCHITECTURE=amd64; elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then ARCHITECTURE=arm64; elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then ARCHITECTURE=aarch64; else ARCHITECTURE=unsupported; fi \ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then ARCHITECTURE=amd64; elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then ARCHITECTURE=arm64; elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then ARCHITECTURE=aarch64; else ARCHITECTURE=unsupported; fi \
&& wget -P /app https://go.dev/dl/go1.17.5.linux-${ARCHITECTURE}.tar.gz \ && wget -P /app https://go.dev/dl/go1.18.10.linux-${ARCHITECTURE}.tar.gz \
&& tar -C /usr/local -xzf /app/go1.17.5.linux-${ARCHITECTURE}.tar.gz && tar -C /usr/local -xzf /app/go1.18.10.linux-${ARCHITECTURE}.tar.gz
RUN git clone https://github.com/balzack/databag.git /app/databag RUN git clone https://github.com/balzack/databag.git /app/databag

View File

@ -37,6 +37,7 @@ func GetAccountStatus(w http.ResponseWriter, r *http.Request) {
status.Searchable = account.Searchable status.Searchable = account.Searchable
status.Sealable = true status.Sealable = true
status.EnableIce = getBoolConfigValue(CNFEnableIce, false) status.EnableIce = getBoolConfigValue(CNFEnableIce, false)
status.AllowUnsealed = getBoolConfigValue(CNFAllowUnsealed, false)
status.PushEnabled = session.PushEnabled status.PushEnabled = session.PushEnabled
status.Seal = seal status.Seal = seal
WriteResponse(w, status) WriteResponse(w, status)

View File

@ -17,6 +17,7 @@ func GetNodeConfig(w http.ResponseWriter, r *http.Request) {
var config NodeConfig var config NodeConfig
config.Domain = getStrConfigValue(CNFDomain, "") config.Domain = getStrConfigValue(CNFDomain, "")
config.AccountStorage = getNumConfigValue(CNFStorage, 0) config.AccountStorage = getNumConfigValue(CNFStorage, 0)
config.AllowUnsealed = getBoolConfigValue(CNFAllowUnsealed, false)
config.EnableImage = getBoolConfigValue(CNFEnableImage, true) config.EnableImage = getBoolConfigValue(CNFEnableImage, true)
config.EnableAudio = getBoolConfigValue(CNFEnableAudio, true) config.EnableAudio = getBoolConfigValue(CNFEnableAudio, true)
config.EnableVideo = getBoolConfigValue(CNFEnableVideo, true) config.EnableVideo = getBoolConfigValue(CNFEnableVideo, true)

View File

@ -69,6 +69,14 @@ func SetNodeConfig(w http.ResponseWriter, r *http.Request) {
return res return res
} }
// upsert allow unsealed channels
if res := tx.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "config_id"}},
DoUpdates: clause.AssignmentColumns([]string{"bool_value"}),
}).Create(&store.Config{ConfigID: CNFAllowUnsealed, BoolValue: config.AllowUnsealed}).Error; res != nil {
return res
}
// upsert push supported // upsert push supported
if res := tx.Clauses(clause.OnConflict{ if res := tx.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "config_id"}}, Columns: []clause.Column{{Name: "config_id"}},

View File

@ -33,6 +33,9 @@ const CNFAssetPath = "asset_path"
//CNFScriptPath specifies the path where transform scripts are found //CNFScriptPath specifies the path where transform scripts are found
const CNFScriptPath = "script_path" const CNFScriptPath = "script_path"
//CNFEnableVideo specifies whether node can process video assets
const CNFAllowUnsealed = "allow_unsealed"
//CNFEnableImage specifies whether node can process image assets //CNFEnableImage specifies whether node can process image assets
const CNFEnableImage = "enable_image" const CNFEnableImage = "enable_image"

View File

@ -42,6 +42,8 @@ type AccountStatus struct {
Seal *Seal `json:"seal,omitempty"` Seal *Seal `json:"seal,omitempty"`
EnableIce bool `json:"enableIce"` EnableIce bool `json:"enableIce"`
AllowUnsealed bool `json:"allowUnsealed"`
} }
//Announce initial message sent on websocket //Announce initial message sent on websocket
@ -370,6 +372,8 @@ type NodeConfig struct {
AccountStorage int64 `json:"accountStorage"` AccountStorage int64 `json:"accountStorage"`
AllowUnsealed bool `json:"allowUnsealed"`
PushSupported bool `json:"pushSupported"` PushSupported bool `json:"pushSupported"`
EnableOpenAccess bool `json:"enableOpenAccess,omitempty"` EnableOpenAccess bool `json:"enableOpenAccess,omitempty"`

View File

@ -139,6 +139,11 @@ export function Dashboard() {
<Switch onChange={(e) => actions.setPushSupported(e)} size="small" <Switch onChange={(e) => actions.setPushSupported(e)} size="small"
defaultChecked={true} checked={state.pushSupported} /> defaultChecked={true} checked={state.pushSupported} />
</div> </div>
<div className="field">
<div>Allow Unsealed Topics:&nbsp;</div>
<Switch onChange={(e) => actions.setAllowUnsealed(e)} size="small"
defaultChecked={true} checked={state.allowUnsealed} />
</div>
<div className="field label"> <div className="field label">
<span>Topic Content:</span> <span>Topic Content:</span>
</div> </div>

View File

@ -14,6 +14,7 @@ export function useDashboard() {
accountStorage: null, accountStorage: null,
keyType: null, keyType: null,
pushSupported: null, pushSupported: null,
allowUnsealed: null,
enableImage: null, enableImage: null,
enableAudio: null, enableAudio: null,
enableVideo: null, enableVideo: null,
@ -84,6 +85,9 @@ export function useDashboard() {
setPushSupported: (pushSupported) => { setPushSupported: (pushSupported) => {
updateState({ pushSupported }); updateState({ pushSupported });
}, },
setAllowUnsealed: (allowUnsealed) => {
updateState({ allowUnsealed });
},
setEnableImage: (enableImage) => { setEnableImage: (enableImage) => {
updateState({ enableImage }); updateState({ enableImage });
}, },
@ -125,9 +129,9 @@ export function useDashboard() {
if (!state.busy) { if (!state.busy) {
updateState({ busy: true }); updateState({ busy: true });
try { try {
const { domain, keyType, accountStorage, pushSupported, enableImage, enableAudio, enableVideo, enableIce, iceUrl, iceUsername, icePassword, enableOpenAccess, openAccessLimit } = state; const { domain, keyType, accountStorage, pushSupported, allowUnsealed, enableImage, enableAudio, enableVideo, enableIce, iceUrl, iceUsername, icePassword, enableOpenAccess, openAccessLimit } = state;
const storage = accountStorage * 1073741824; const storage = accountStorage * 1073741824;
const config = { domain, accountStorage: storage, keyType, enableImage, enableAudio, enableVideo, pushSupported, enableIce, iceUrl, iceUsername, icePassword, enableOpenAccess, openAccessLimit }; const config = { domain, accountStorage: storage, keyType, enableImage, enableAudio, enableVideo, pushSupported, allowUnsealed, enableIce, iceUrl, iceUsername, icePassword, enableOpenAccess, openAccessLimit };
await setNodeConfig(app.state.adminToken, config); await setNodeConfig(app.state.adminToken, config);
updateState({ busy: false, showSettings: false }); updateState({ busy: false, showSettings: false });
} }
@ -143,9 +147,9 @@ export function useDashboard() {
const syncConfig = async () => { const syncConfig = async () => {
try { try {
const config = await getNodeConfig(app.state.adminToken); const config = await getNodeConfig(app.state.adminToken);
const { storage, domain, keyType, pushSupported, enableImage, enableAudio, enableVideo, enableIce, iceUrl, iceUsername, icePassword, enableOpenAccess, openAccessLimit } = config; const { storage, domain, keyType, pushSupported, allowUnsealed, enableImage, enableAudio, enableVideo, enableIce, iceUrl, iceUsername, icePassword, enableOpenAccess, openAccessLimit } = config;
const accountStorage = Math.ceil(storage / 1073741824); const accountStorage = Math.ceil(storage / 1073741824);
updateState({ configError: false, domain, accountStorage, keyType, enableImage, enableAudio, enableVideo, pushSupported, enableIce, iceUrl, iceUsername, icePassword, enableOpenAccess, openAccessLimit }); updateState({ configError: false, domain, accountStorage, keyType, enableImage, enableAudio, enableVideo, pushSupported, allowUnsealed, enableIce, iceUrl, iceUsername, icePassword, enableOpenAccess, openAccessLimit });
} }
catch(err) { catch(err) {
console.log(err); console.log(err);

View File

@ -23,7 +23,7 @@ export function Channels({ open, active }) {
</div> </div>
{ state.display === 'small' && ( { state.display === 'small' && (
<div class="inline"> <div class="inline">
<Button type="primary" icon={<CommentOutlined />} onClick={actions.setShowAdd}>New</Button> <Button type="primary" disabled={!state.allowAdd} icon={<CommentOutlined />} onClick={actions.setShowAdd}>New</Button>
</div> </div>
)} )}
</div> </div>
@ -42,10 +42,10 @@ export function Channels({ open, active }) {
</div> </div>
{ state.display !== 'small' && ( { state.display !== 'small' && (
<div class="bar"> <div class="bar">
<Button type="primary" icon={<CommentOutlined />} onClick={actions.setShowAdd}>New Topic</Button> <Button type="primary" disabled={!state.allowAdd} icon={<CommentOutlined />} onClick={actions.setShowAdd}>New Topic</Button>
</div> </div>
)} )}
<Modal bodyStyle={{ padding: 16 }} title="New Topic" centered visible={state.showAdd} footer={null} destroyOnClose={true} <Modal bodyStyle={{ padding: 16 }} title="New Topic" centered visible={state.showAdd && state.allowAdd} footer={null} destroyOnClose={true}
onCancel={actions.clearShowAdd}> onCancel={actions.clearShowAdd}>
<AddChannel added={added} cancelled={actions.clearShowAdd} /> <AddChannel added={added} cancelled={actions.clearShowAdd} />
</Modal> </Modal>

View File

@ -45,7 +45,7 @@ export function AddChannel({ added, cancelled }) {
</div> </div>
<AddFooter> <AddFooter>
<div class="seal"> <div class="seal">
{ state.sealable && ( { state.sealable && state.allowUnsealed && (
<> <>
<Switch checked={state.seal} onChange={actions.setSeal} size="small" /> <Switch checked={state.seal} onChange={actions.setSeal} size="small" />
<span class="sealText">Sealed Channel</span> <span class="sealText">Sealed Channel</span>

View File

@ -10,6 +10,7 @@ export function useAddChannel() {
sealable: false, sealable: false,
busy: false, busy: false,
showAdd: false, showAdd: false,
allowUnsealed: false,
subject: null, subject: null,
members: new Set(), members: new Set(),
seal: false, seal: false,
@ -25,11 +26,12 @@ export function useAddChannel() {
useEffect(() => { useEffect(() => {
const { seal, sealKey } = account.state; const { seal, sealKey } = account.state;
const allowUnsealed = account.state.status?.allowUnsealed;
if (seal?.publicKey && sealKey?.public && sealKey?.private && seal.publicKey === sealKey.public) { if (seal?.publicKey && sealKey?.public && sealKey?.private && seal.publicKey === sealKey.public) {
updateState({ seal: false, sealable: true }); updateState({ seal: false, sealable: true, allowUnsealed });
} }
else { else {
updateState({ seal: false, sealable: false }); updateState({ seal: false, sealable: false, allowUnsealed });
} }
}, [account.state]); }, [account.state]);
@ -94,7 +96,7 @@ export function useAddChannel() {
updateState({ subject }); updateState({ subject });
}, },
cardFilter: (card) => { cardFilter: (card) => {
if (state.seal) { if (state.seal || !state.allowUnsealed) {
return card?.data?.cardDetail?.status === 'connected' && card?.data?.cardProfile?.seal; return card?.data?.cardDetail?.status === 'connected' && card?.data?.cardProfile?.seal;
} }
return card?.data?.cardDetail?.status === 'connected'; return card?.data?.cardDetail?.status === 'connected';

View File

@ -16,6 +16,7 @@ export function useChannels() {
display: null, display: null,
channels: [], channels: [],
showAdd: false, showAdd: false,
allowAdd: false,
}); });
const profile = useContext(ProfileContext); const profile = useContext(ProfileContext);
@ -253,7 +254,11 @@ export function useChannels() {
} }
}); });
updateState({ channels: filtered }); const sealKey = account.state.sealKey?.public && account.state.sealKey?.private;
const allowUnsealed = account.state.status?.allowUnsealed;
const allowAdd = allowUnsealed || sealKey;
updateState({ channels: filtered, allowAdd });
// eslint-disable-next-line // eslint-disable-next-line
}, [account.state, store.state, card.state, channel.state, filter]); }, [account.state, store.state, card.state, channel.state, filter]);