Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/Domain/Nodes/Actions/GetAccessibleNodesAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public function execute(Group $group)
$query
// Only return nodes for the selected group
->whereGroupId($group->id)
// Eager load the group relationship
->with(['group'])
// Don't return nodes without a node_id (MQTT bridges)
->whereNotNull('nodes.node_id')
// If we have a search term then apply then filter only the models that were returned from the search
Expand Down
29 changes: 28 additions & 1 deletion app/Http/Controllers/EdgeAgentConfigurationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
use App\Domain\Nodes\Models\Node;
use App\Exceptions\ActionFailException;
use App\Http\Requests\GetEdgeAgentConfigurationRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class EdgeAgentConfigurationController extends Controller
Expand Down Expand Up @@ -38,4 +37,32 @@ public function show(GetEdgeAgentConfigurationRequest $request)

return action_success(Storage::disk('edge-agent-configs')->get($node->activeEdgeNodeConfiguration->file));
}

public function download(GetEdgeAgentConfigurationRequest $request)
{
// Authenticate the request
$validated = $request->validated();

// Get the node
$node = Node::where('uuid', $validated['node_id'])->first();
if (! $node) {
throw new ActionFailException(
'The node does not exist.', 404
);
}

// // Allow admins to get the config with any password
// if (!auth()->user() || !auth()->user()->administrator) {
// (new AuthenticateKerberosPrincipalAction)->execute($node->principal, $validated['config_password']);
// }

if ($node->activeEdgeNodeConfiguration === null) {
throw new ActionFailException(
'This node does not have an active Edge Agent configuration. Ensure that it has both an active Origin Map and an active Device Connection in the Factory+ manager.'
);
}

return action_success(Storage::disk('edge-agent-configs')->get($node->activeEdgeNodeConfiguration->file));
}

}
39 changes: 39 additions & 0 deletions resources/js/components/Containers/NodeContainer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@
<div class="flex items-center justify-between gap-2">
<a href="#" class="text-gray-500 font-semibold hover:text-gray-700 mb-1">{{item.node_id}}</a>
<div class="flex items-center justify-center gap-0">
<button v-if="$root.$data.user.administrator" type="button"
@mouseup="downloadNodeConfig(item)"
v-tooltip="'Download Node Configuration'"
class="fpl-button-info w-6 !h-6">
<i class="fa-sharp fa-solid fa-download text-xs"></i>
</button>
<button v-if="$root.$data.user.administrator" type="button"
@mouseup="showNodeUserDialog(item)"
v-tooltip="'Manage User Access'"
Expand Down Expand Up @@ -212,6 +218,39 @@ export default {
})
},

downloadNodeConfig(node) {

const fileName = `FactoryPlus_${node.group.name}_${node.node_id}`

axios.post('/api/download-edge-agent-config', {
node_id: node.uuid,
config_password: 'not_required_as_admin'
}).then(response => {
// Get the file content from the response
const fileContent = response.data.data;

// Create a Blob from the content
const blob = new Blob([fileContent], { type: 'application/json' });

// Generate a URL for the Blob
const downloadUrl = window.URL.createObjectURL(blob);

// Create an anchor element to trigger the download
const link = document.createElement('a');
link.href = downloadUrl;
link.setAttribute('download', `${fileName}.json`); // Set the desired filename
document.body.appendChild(link);
link.click();
link.remove(); // Clean up the DOM
}).catch(error => {
if (error.response && error.response.status === 401) {
this.goto_url('/login');
} else {
this.handleError(error);
}
});
},

maybeDeleteNode(group, node) {
if (this.deletingNode) return;

Expand Down
1 change: 1 addition & 0 deletions routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@

// ------ Edge Agent Config ------ //
Route::post('edge-agent-config', [EdgeAgentConfigurationController::class, 'show']);
Route::post('download-edge-agent-config', [EdgeAgentConfigurationController::class, 'download']);

// ------ Edge Agents ------ //
Route::middleware('auth:api')->get('/edge-agents', [EdgeAgentController::class, 'index']);
Expand Down