mirror of https://github.com/gophish/gophish
Added Education Template for Creating Educational Redirect Pages Inside Static Folder
gophish.go: /controllers is now imported from relevant local directory controllers/route.go: Added handling for /education URL, including handling AJAX POST requests templates/education.html: New template for creating, editing and managing HTML pages inside the static folder. Pages in this directory are served by the phishing server, and can be redirected to through landing pages templates/landing_pages.html: Added some information to the hover help icon by the redirect field, and a dropdown that suggests files from the static folder. /templates: Most of the other templates had the education page href added to their menuspull/662/head
parent
ad45915aa2
commit
e263f35fc6
|
@ -3,9 +3,12 @@ package controllers
|
|||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/gophish/gophish/auth"
|
||||
"github.com/gophish/gophish/config"
|
||||
|
@ -29,6 +32,9 @@ func CreateAdminRouter() http.Handler {
|
|||
router.HandleFunc("/login", Login)
|
||||
router.HandleFunc("/logout", Use(Logout, mid.RequireLogin))
|
||||
router.HandleFunc("/campaigns", Use(Campaigns, mid.RequireLogin))
|
||||
|
||||
router.HandleFunc("/education", Use(Education, mid.RequireLogin))
|
||||
|
||||
router.HandleFunc("/campaigns/{id:[0-9]+}", Use(CampaignID, mid.RequireLogin))
|
||||
router.HandleFunc("/templates", Use(Templates, mid.RequireLogin))
|
||||
router.HandleFunc("/users", Use(Users, mid.RequireLogin))
|
||||
|
@ -196,7 +202,27 @@ func LandingPages(w http.ResponseWriter, r *http.Request) {
|
|||
Title string
|
||||
Flashes []interface{}
|
||||
Token string
|
||||
List []string
|
||||
}{Title: "Landing Pages", User: ctx.Get(r, "user").(models.User), Token: csrf.Token(r)}
|
||||
|
||||
pwd, _ := os.Getwd()
|
||||
files, _ := filepath.Glob(pwd + "\\static\\endpoint\\[a-z,A-Z,0-9]*")
|
||||
//
|
||||
//files, _ := filepath.Glob("C:\\Users\\cpatterson\\Desktop\\gophish-master\\static\\endpoint/[a-z,A-Z,0-9]*")
|
||||
|
||||
if len(files) > 0 {
|
||||
|
||||
for index := range files {
|
||||
|
||||
//Get the filename by splitting off the directory portion
|
||||
parts := strings.Split(files[index], "\\")
|
||||
string := parts[len(parts)-1]
|
||||
|
||||
//Add this file to the list of files to be returned to the user
|
||||
params.List = append(params.List, string)
|
||||
}
|
||||
}
|
||||
|
||||
getTemplate(w, "landing_pages").ExecuteTemplate(w, "base", params)
|
||||
}
|
||||
|
||||
|
@ -212,6 +238,118 @@ func SendingProfiles(w http.ResponseWriter, r *http.Request) {
|
|||
getTemplate(w, "sending_profiles").ExecuteTemplate(w, "base", params)
|
||||
}
|
||||
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//EDUCATION TEMPLATE FUNCTIONS
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
// Proxy struct holds templates found by server
|
||||
type Proxy struct {
|
||||
Name string
|
||||
Body string
|
||||
}
|
||||
|
||||
// Education handles the default path and template execution
|
||||
func Education(w http.ResponseWriter, r *http.Request) {
|
||||
switch {
|
||||
case r.Method == "GET":
|
||||
params := struct {
|
||||
User models.User
|
||||
Title string
|
||||
Message string
|
||||
Token string
|
||||
List []Proxy
|
||||
}{Title: "Education", User: ctx.Get(r, "user").(models.User), Token: csrf.Token(r)}
|
||||
|
||||
//Return a list of every file in the endpoint directory to return to the user, excluding the .gitignore, using relevant path
|
||||
pwd, _ := os.Getwd()
|
||||
files, _ := filepath.Glob(pwd + "\\static\\endpoint\\[a-z,A-Z,0-9]*")
|
||||
|
||||
if len(files) > 0 {
|
||||
|
||||
//For each file found in the list
|
||||
for index := range files {
|
||||
|
||||
file, err := os.Stat(files[index])
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
//Find the last time the file was modified
|
||||
modifiedtime := file.ModTime()
|
||||
|
||||
//Get the filename by splitting off the directory portion
|
||||
parts := strings.Split(files[index], "\\")
|
||||
string := parts[len(parts)-1][:len(parts[len(parts)-1])-5]
|
||||
|
||||
//Add this file to the list of files to be returned to the user
|
||||
params.List = append(params.List, Proxy{string, modifiedtime.Format("Mon Jan _2 15:04:05 2006")})
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
//If there weren't any education template files found, display this message to the user
|
||||
params.Message = "No education templates created yet. Let's create one!"
|
||||
|
||||
}
|
||||
|
||||
//Execute the template and send it to the user
|
||||
getTemplate(w, "education").ExecuteTemplate(w, "base", params)
|
||||
|
||||
//If we are receiving AJAX POST REQUESTS
|
||||
case r.Method == "POST":
|
||||
|
||||
//PARSE THE FORM
|
||||
r.ParseForm()
|
||||
|
||||
//For the actions specified, save the form as a file on disk, return the file contents to be edited, or delete the file on disk
|
||||
if r.Form.Get("action") == "SUBMIT" {
|
||||
|
||||
pwd, _ := os.Getwd()
|
||||
|
||||
err := ioutil.WriteFile(pwd+"\\static\\endpoint/"+r.Form.Get("name")+".html", []byte(r.Form.Get("body")), 0644)
|
||||
if err != nil {
|
||||
JSONResponse(w, "An error was encountered trying to save your file on server.", http.StatusOK)
|
||||
}
|
||||
|
||||
JSONResponse(w, "Education page saved successfully.", http.StatusOK)
|
||||
|
||||
} else if r.Form.Get("action") == "EDIT" {
|
||||
|
||||
pwd, _ := os.Getwd()
|
||||
|
||||
b, err := ioutil.ReadFile(pwd + "\\static\\endpoint/" + r.Form.Get("name") + ".html")
|
||||
if err != nil {
|
||||
JSONResponse(w, "An error was encountered attempting to retrieve the saved file on server.", http.StatusOK)
|
||||
}
|
||||
|
||||
JSONResponse(w, string(b), http.StatusOK)
|
||||
|
||||
} else if r.Form.Get("action") == "DELETE" {
|
||||
|
||||
pwd, _ := os.Getwd()
|
||||
|
||||
err := os.Remove(pwd + "\\static\\endpoint/" + r.Form.Get("name") + ".html")
|
||||
|
||||
if err != nil {
|
||||
JSONResponse(w, "An error was encountered trying to delete the file on the server.", http.StatusOK)
|
||||
return
|
||||
}
|
||||
|
||||
JSONResponse(w, "File deleted successfully.", http.StatusOK)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------------------
|
||||
//END OF EDUCATION TEMPLATE FUNCTIONS
|
||||
//--------------------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
// Settings handles the changing of settings
|
||||
func Settings(w http.ResponseWriter, r *http.Request) {
|
||||
switch {
|
||||
|
|
14
gophish.go
14
gophish.go
|
@ -2,21 +2,16 @@ package main
|
|||
|
||||
/*
|
||||
gophish - Open-Source Phishing Framework
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Jordan Wright
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
@ -33,12 +28,10 @@ import (
|
|||
"os"
|
||||
"sync"
|
||||
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
|
||||
"./controllers"
|
||||
"github.com/NYTimes/gziphandler"
|
||||
"github.com/gophish/gophish/auth"
|
||||
"github.com/gophish/gophish/config"
|
||||
"github.com/gophish/gophish/controllers"
|
||||
"github.com/gophish/gophish/models"
|
||||
"github.com/gophish/gophish/util"
|
||||
"github.com/gorilla/handlers"
|
||||
|
@ -46,14 +39,9 @@ import (
|
|||
|
||||
var (
|
||||
Logger = log.New(os.Stdout, " ", log.Ldate|log.Ltime|log.Lshortfile)
|
||||
|
||||
configPath = kingpin.Flag("config", "Location of config.json.").Default("./config.json").String()
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Parse the CLI flags and load the config
|
||||
kingpin.Parse()
|
||||
config.LoadConfig(*configPath)
|
||||
// Setup the global variables and settings
|
||||
err := models.Setup()
|
||||
if err != nil {
|
||||
|
|
|
@ -53,6 +53,8 @@
|
|||
</li>
|
||||
<li><a href="/landing_pages">Landing Pages</a>
|
||||
</li>
|
||||
<li><a href="/education">Education</a>
|
||||
</li>
|
||||
<li><a href="/sending_profiles">Sending Profiles</a>
|
||||
</li>
|
||||
<li><a href="/settings">Settings</a>
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
<li><a href="/templates">Email Templates</a>
|
||||
</li>
|
||||
<li><a href="/landing_pages">Landing Pages</a>
|
||||
</li>
|
||||
<li><a href="/education">Education</a>
|
||||
</li>
|
||||
<li><a href="/sending_profiles">Sending Profiles</a>
|
||||
</li>
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
<li><a href="/templates">Email Templates</a>
|
||||
</li>
|
||||
<li><a href="/landing_pages">Landing Pages</a>
|
||||
</li>
|
||||
<li><a href="/education">Education</a>
|
||||
</li>
|
||||
<li><a href="/sending_profiles">Sending Profiles</a>
|
||||
</li>
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
</li>
|
||||
<li><a href="/landing_pages">Landing Pages</a>
|
||||
</li>
|
||||
<li><a href="/education">Education</a>
|
||||
</li>
|
||||
<li><a href="/sending_profiles">Sending Profiles</a>
|
||||
</li>
|
||||
<li><a href="/settings">Settings</a>
|
||||
|
@ -45,9 +47,15 @@
|
|||
</div>
|
||||
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
||||
<p style="text-align:center;">Average Phishing Results</p>
|
||||
<div id="stats_chart" class="col-lg-7 col-md-7"></div>
|
||||
<div class="col-lg-5 col-md-5">
|
||||
<ul id="stats_chart_legend" class="chartist-legend">
|
||||
<div id="average_chart" class="col-lg-7 col-md-7"></div>
|
||||
<div id="average_chart_legend" class="col-lg-5 col-md-5">
|
||||
<ul class="chartist-legend">
|
||||
<li>
|
||||
<span style="background-color:#f05b4f;"></span> Successful Phishes
|
||||
</li>
|
||||
<li>
|
||||
<span style="background-color:#1abc9c;"></span> Unsuccessful Phishes
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,205 @@
|
|||
{{define "body"}}
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-sm-3 col-md-2 sidebar">
|
||||
<ul class="nav nav-sidebar">
|
||||
<li><a href="/">Dashboard</a>
|
||||
</li>
|
||||
<li><a href="/campaigns">Campaigns</a>
|
||||
</li>
|
||||
<li><a href="/users">Users & Groups</a>
|
||||
</li>
|
||||
<li><a href="/templates">Email Templates</a>
|
||||
</li>
|
||||
<li><a href="/landing_pages">Landing Pages</a>
|
||||
</li>
|
||||
<li><a href="/education">Education</a>
|
||||
</li>
|
||||
<li><a href="/sending_profiles">Sending Profiles</a>
|
||||
</li>
|
||||
<li><a href="/settings">Settings</a>
|
||||
</li>
|
||||
<li><hr></li>
|
||||
<li><a href="https://gophish.gitbooks.io/user-guide/content/">User Guide</a>
|
||||
</li>
|
||||
<li><a href="/api/">API Documentation</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
||||
<h1 class="page-header">
|
||||
Education
|
||||
</h1>
|
||||
<div id="flashes" class="row"></div>
|
||||
<div class="row">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal"><i class="fa fa-plus"></i> New Page</button>
|
||||
</div>
|
||||
|
||||
<div id="emptyMessage" class="row" {{if not .Message}} style="display:none;"{{end}}>
|
||||
<div class="alert alert-info">
|
||||
{{if .Message}} {{.Message}} {{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{if .List}}
|
||||
|
||||
<div class="row">
|
||||
<table id="pagesTable" class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Last Modified Date</th>
|
||||
<th class="col-md-2 no-sort"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
{{range $index,$article := .List }}
|
||||
|
||||
<tbody id="t_{{$index}}">
|
||||
|
||||
<tr role="row">
|
||||
<td id="edu_name_{{$index}}"class="sorting_1">{{- .Name -}}</td>
|
||||
<td>{{- .Body -}}</td>
|
||||
<td class="col-md-2 no-sort"></td>
|
||||
<td>
|
||||
|
||||
<div class="pull-right">
|
||||
|
||||
<span data-toggle="modal" data-target="#modal"><button class="btn btn-primary" data-toggle="tooltip" data-placement="left" title="" onclick="edit({{$index}})" data-original-title="Edit Page"> <i class="fa fa-pencil"></i> </button></span>
|
||||
|
||||
<button class="btn btn-danger" data-toggle="tooltip" data-placement="left" title="" onclick="deletePage({{$index}})" data-original-title="Delete Page"><i class="fa fa-trash-o"></i> </button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
{{end}}
|
||||
|
||||
</table>
|
||||
</div>
|
||||
<div class="dataTables_info" id="pagesTable_info" role="status" aria-live="polite">Showing {{len .List}} of {{len .List}} entries</div>
|
||||
|
||||
{{end}}
|
||||
|
||||
</div>
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="modalLabel">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<!-- New Template Modal -->
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="dismiss()"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="modalLabel">New Landing Page</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row" id="modal.flashes"></div>
|
||||
<label class="control-label" for="name">Name:</label>
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" placeholder="Page name" id="name" autofocus/>
|
||||
</div>
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li class="active" role="html"><a href="#html" aria-controls="html" role="tab" data-toggle="tab">HTML</a></li>
|
||||
</ul>
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active" id="html">
|
||||
<textarea id="html_editor"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" data-dismiss="modal" class="btn btn-default" onclick="dismiss()">Cancel</button>
|
||||
<button type="button" data-dismiss="modal" class="btn btn-primary" id="modalSubmit" onclick="submar()">Save Page</button>
|
||||
</div>
|
||||
<input type="hidden" name="csrf_token" value="{{.Token}}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Modal -->
|
||||
|
||||
{{end}}
|
||||
{{define "scripts"}}
|
||||
<script src="/js/src/vendor/ckeditor/ckeditor.js"></script>
|
||||
<script src="/js/src/vendor/ckeditor/adapters/jquery.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
CKEDITOR.replace( 'html_editor' );
|
||||
|
||||
var token = document.getElementsByName("csrf_token")[0].value;
|
||||
|
||||
function submar() {
|
||||
var name = document.getElementById("name").value;
|
||||
var body = CKEDITOR.instances.html_editor.getData();
|
||||
var formData = {"action": "SUBMIT", "name": name, "body":body, "csrf_token": token};
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : 'education',
|
||||
data : formData,
|
||||
dataType : 'json',
|
||||
encode : true
|
||||
})
|
||||
.done(function(data) {
|
||||
document.getElementById('emptyMessage').style.display = "block";
|
||||
document.getElementsByClassName('alert alert-info')[0].innerHTML = data;
|
||||
});
|
||||
event.preventDefault();
|
||||
dismiss();
|
||||
}
|
||||
|
||||
function dismiss() {
|
||||
$("#name").val("")
|
||||
CKEDITOR.instances.html_editor.setData('');
|
||||
$("#modal").modal('hide')
|
||||
}
|
||||
|
||||
function edit(id) {
|
||||
var iden = "edu_name_".concat(id);
|
||||
var name = document.getElementById(iden).innerHTML;
|
||||
var formData = {"action": "EDIT", "name": name, "csrf_token": token};
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : 'education',
|
||||
data : formData,
|
||||
dataType : 'json',
|
||||
encode : true
|
||||
})
|
||||
.done(function(data) {
|
||||
document.getElementById("name").value = name;
|
||||
CKEDITOR.instances.html_editor.setData(data);
|
||||
});
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
function deletePage(id) {
|
||||
var iden = "edu_name_".concat(id);
|
||||
var name = document.getElementById(iden).innerHTML;
|
||||
var formData = {"action": "DELETE", "name": name, "csrf_token": token};
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : 'education',
|
||||
data : formData,
|
||||
dataType : 'json',
|
||||
encode : true
|
||||
})
|
||||
.done(function(data) {
|
||||
document.getElementById('emptyMessage').style.display = "block";
|
||||
document.getElementsByClassName('alert alert-info')[0].innerHTML = data;
|
||||
var tbod = "t_".concat(id);
|
||||
var table = document.getElementById(tbod);
|
||||
table.parentNode.removeChild(table);
|
||||
});
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
{{end}}
|
||||
|
||||
|
||||
|
|
@ -12,6 +12,8 @@
|
|||
<li><a href="/templates">Email Templates</a>
|
||||
</li>
|
||||
<li class="active"><a href="/landing_pages">Landing Pages</a>
|
||||
</li>
|
||||
<li><a href="/education">Education</a>
|
||||
</li>
|
||||
<li><a href="/sending_profiles">Sending Profiles</a>
|
||||
</li>
|
||||
|
@ -97,9 +99,33 @@
|
|||
</div>
|
||||
</div>
|
||||
<div id="redirect_url">
|
||||
<label class="control-label" for="redirect_url_input">Redirect to: <i class="fa fa-question-circle" data-toggle="tooltip" data-placement="right" title="This option lets you redirect the user to a page after credentials are submitted."></i></label>
|
||||
<label class="control-label" for="redirect_url_input">Redirect to: <i class="fa fa-question-circle" data-toggle="tooltip" data-placement="right" title="Redirect the user to a page after submitting credentials. Redirect to Education pages with the following URL: http://phishing_server/static/ + [name] +.html"></i></label>
|
||||
<div class="form-group">
|
||||
<input id="redirect_url_input" class="form-control" placeholder="http://example.com"/>
|
||||
|
||||
|
||||
|
||||
<input id="redirect_url_input" class="form-control" list="browsers" name="browser">
|
||||
|
||||
|
||||
{{if .List}}
|
||||
|
||||
|
||||
<datalist id="browsers">
|
||||
|
||||
|
||||
{{range $article := .List }}
|
||||
|
||||
|
||||
<option value="http://phishing_server/static/{{$article}}">
|
||||
|
||||
{{end}}
|
||||
|
||||
</datalist>
|
||||
|
||||
{{end}}
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
<li><a href="/templates">Email Templates</a>
|
||||
</li>
|
||||
<li><a href="/landing_pages">Landing Pages</a>
|
||||
</li>
|
||||
<li><a href="/education">Education</a>
|
||||
</li>
|
||||
<li class="active"><a href="/sending_profiles">Sending Profiles</a>
|
||||
</li>
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
<li><a href="/templates">Email Templates</a>
|
||||
</li>
|
||||
<li><a href="/landing_pages">Landing Pages</a>
|
||||
</li>
|
||||
<li><a href="/education">Education</a>
|
||||
</li>
|
||||
<li><a href="/sending_profiles">Sending Profiles</a>
|
||||
</li>
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
<li class="active"><a href="/templates">Email Templates</a>
|
||||
</li>
|
||||
<li><a href="/landing_pages">Landing Pages</a>
|
||||
</li>
|
||||
<li><a href="/education">Education</a>
|
||||
</li>
|
||||
<li><a href="/sending_profiles">Sending Profiles</a>
|
||||
</li>
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
<li><a href="/templates">Email Templates</a>
|
||||
</li>
|
||||
<li><a href="/landing_pages">Landing Pages</a>
|
||||
</li>
|
||||
<li><a href="/education">Education</a>
|
||||
</li>
|
||||
<li><a href="/sending_profiles">Sending Profiles</a>
|
||||
</li>
|
||||
|
|
Loading…
Reference in New Issue