gophish-ruby 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -0
- data/README.md +342 -2
- data/Rakefile +1 -1
- data/docs/API_REFERENCE.md +572 -4
- data/docs/EXAMPLES.md +984 -0
- data/docs/GETTING_STARTED.md +239 -0
- data/lib/gophish/base.rb +6 -24
- data/lib/gophish/group.rb +2 -0
- data/lib/gophish/page.rb +56 -0
- data/lib/gophish/template.rb +94 -0
- data/lib/gophish/version.rb +1 -1
- data/lib/gophish-ruby.rb +2 -1
- metadata +3 -1
data/docs/API_REFERENCE.md
CHANGED
@@ -7,6 +7,8 @@ This document provides detailed API reference for the Gophish Ruby SDK.
|
|
7
7
|
- [Configuration](#configuration)
|
8
8
|
- [Base Class](#base-class)
|
9
9
|
- [Group Class](#group-class)
|
10
|
+
- [Template Class](#template-class)
|
11
|
+
- [Page Class](#page-class)
|
10
12
|
- [Error Handling](#error-handling)
|
11
13
|
- [Examples](#examples)
|
12
14
|
|
@@ -125,7 +127,7 @@ Create or update the resource on the server.
|
|
125
127
|
**Side Effects:**
|
126
128
|
|
127
129
|
- Sets `@persisted` to true on success
|
128
|
-
- Clears
|
130
|
+
- Clears change tracking information on success
|
129
131
|
- Adds errors to `#errors` on failure
|
130
132
|
|
131
133
|
**Example:**
|
@@ -207,7 +209,7 @@ group = Gophish::Group.new
|
|
207
209
|
puts group.new_record? # => true
|
208
210
|
```
|
209
211
|
|
210
|
-
##### `#
|
212
|
+
##### `#changed`
|
211
213
|
|
212
214
|
Get array of attribute names that have changed.
|
213
215
|
|
@@ -218,7 +220,23 @@ Get array of attribute names that have changed.
|
|
218
220
|
```ruby
|
219
221
|
group = Gophish::Group.find(1)
|
220
222
|
group.name = "New Name"
|
221
|
-
puts group.
|
223
|
+
puts group.changed # => ["name"]
|
224
|
+
```
|
225
|
+
|
226
|
+
##### `#changed?`
|
227
|
+
|
228
|
+
Check if any attributes have changed.
|
229
|
+
|
230
|
+
**Returns:** Boolean
|
231
|
+
|
232
|
+
**Example:**
|
233
|
+
|
234
|
+
```ruby
|
235
|
+
group = Gophish::Group.find(1)
|
236
|
+
puts group.changed? # => false
|
237
|
+
|
238
|
+
group.name = "New Name"
|
239
|
+
puts group.changed? # => true
|
222
240
|
```
|
223
241
|
|
224
242
|
##### `#attribute_changed?(attr)`
|
@@ -236,8 +254,8 @@ Check if a specific attribute has changed.
|
|
236
254
|
```ruby
|
237
255
|
group = Gophish::Group.find(1)
|
238
256
|
group.name = "New Name"
|
257
|
+
puts group.name_changed? # => true (using dynamic method)
|
239
258
|
puts group.attribute_changed?(:name) # => true
|
240
|
-
puts group.attribute_changed?("targets") # => false
|
241
259
|
```
|
242
260
|
|
243
261
|
##### `#attribute_was(attr)`
|
@@ -256,6 +274,7 @@ Get the previous value of a changed attribute.
|
|
256
274
|
group = Gophish::Group.find(1)
|
257
275
|
original_name = group.name
|
258
276
|
group.name = "New Name"
|
277
|
+
puts group.name_was # => original_name (using dynamic method)
|
259
278
|
puts group.attribute_was(:name) # => original_name
|
260
279
|
```
|
261
280
|
|
@@ -376,6 +395,555 @@ group.import_csv(csv_content)
|
|
376
395
|
group.save
|
377
396
|
```
|
378
397
|
|
398
|
+
## Template Class
|
399
|
+
|
400
|
+
The `Gophish::Template` class represents an email template in Gophish.
|
401
|
+
|
402
|
+
### Class: `Gophish::Template < Gophish::Base`
|
403
|
+
|
404
|
+
#### Attributes
|
405
|
+
|
406
|
+
| Attribute | Type | Required | Description |
|
407
|
+
|-----------|------|----------|-------------|
|
408
|
+
| `id` | Integer | No | Unique template identifier (set by server) |
|
409
|
+
| `name` | String | Yes | Template name |
|
410
|
+
| `subject` | String | No | Email subject line |
|
411
|
+
| `text` | String | No | Plain text email content |
|
412
|
+
| `html` | String | No | HTML email content |
|
413
|
+
| `modified_date` | String | No | Last modification timestamp (set by server) |
|
414
|
+
| `attachments` | Array | No | Array of attachment hashes |
|
415
|
+
|
416
|
+
#### Attachment Structure
|
417
|
+
|
418
|
+
Each attachment in the `attachments` array must have:
|
419
|
+
|
420
|
+
| Field | Type | Required | Description |
|
421
|
+
|-------|------|----------|-------------|
|
422
|
+
| `content` | String | Yes | Base64 encoded file content |
|
423
|
+
| `type` | String | Yes | MIME type (e.g., "application/pdf") |
|
424
|
+
| `name` | String | Yes | Filename |
|
425
|
+
|
426
|
+
#### Validations
|
427
|
+
|
428
|
+
- `name` must be present
|
429
|
+
- Must have either `text` or `html` content (or both)
|
430
|
+
- Each attachment must be a Hash with required fields (`content`, `type`, `name`)
|
431
|
+
|
432
|
+
#### Class Methods
|
433
|
+
|
434
|
+
##### `.import_email(content, convert_links: false)`
|
435
|
+
|
436
|
+
Import email content and return template data.
|
437
|
+
|
438
|
+
**Parameters:**
|
439
|
+
|
440
|
+
- `content` (String) - Raw email content (.eml format)
|
441
|
+
- `convert_links` (Boolean) - Whether to convert links for Gophish tracking (default: false)
|
442
|
+
|
443
|
+
**Returns:** Hash of template attributes
|
444
|
+
|
445
|
+
**Raises:**
|
446
|
+
|
447
|
+
- `StandardError` if import fails
|
448
|
+
|
449
|
+
**Example:**
|
450
|
+
|
451
|
+
```ruby
|
452
|
+
email_content = File.read("sample.eml")
|
453
|
+
template_data = Gophish::Template.import_email(email_content, convert_links: true)
|
454
|
+
|
455
|
+
template = Gophish::Template.new(template_data)
|
456
|
+
template.name = "Imported Template"
|
457
|
+
template.save
|
458
|
+
```
|
459
|
+
|
460
|
+
#### Instance Methods
|
461
|
+
|
462
|
+
##### `#add_attachment(content, type, name)`
|
463
|
+
|
464
|
+
Add an attachment to the template.
|
465
|
+
|
466
|
+
**Parameters:**
|
467
|
+
|
468
|
+
- `content` (String) - File content (will be Base64 encoded automatically)
|
469
|
+
- `type` (String) - MIME type
|
470
|
+
- `name` (String) - Filename
|
471
|
+
|
472
|
+
**Returns:** Void
|
473
|
+
|
474
|
+
**Side Effects:**
|
475
|
+
|
476
|
+
- Adds attachment to `attachments` array
|
477
|
+
- Marks `attachments` attribute as changed
|
478
|
+
|
479
|
+
**Example:**
|
480
|
+
|
481
|
+
```ruby
|
482
|
+
template = Gophish::Template.new(name: "Test", html: "<p>Test</p>")
|
483
|
+
file_content = File.read("document.pdf")
|
484
|
+
template.add_attachment(file_content, "application/pdf", "document.pdf")
|
485
|
+
```
|
486
|
+
|
487
|
+
##### `#remove_attachment(name)`
|
488
|
+
|
489
|
+
Remove an attachment by filename.
|
490
|
+
|
491
|
+
**Parameters:**
|
492
|
+
|
493
|
+
- `name` (String) - Filename of attachment to remove
|
494
|
+
|
495
|
+
**Returns:** Void
|
496
|
+
|
497
|
+
**Side Effects:**
|
498
|
+
|
499
|
+
- Removes matching attachment(s) from `attachments` array
|
500
|
+
- Marks `attachments` attribute as changed if any were removed
|
501
|
+
|
502
|
+
**Example:**
|
503
|
+
|
504
|
+
```ruby
|
505
|
+
template.remove_attachment("document.pdf")
|
506
|
+
```
|
507
|
+
|
508
|
+
##### `#has_attachments?`
|
509
|
+
|
510
|
+
Check if template has any attachments.
|
511
|
+
|
512
|
+
**Returns:** Boolean
|
513
|
+
|
514
|
+
**Example:**
|
515
|
+
|
516
|
+
```ruby
|
517
|
+
if template.has_attachments?
|
518
|
+
puts "Template has #{template.attachment_count} attachments"
|
519
|
+
end
|
520
|
+
```
|
521
|
+
|
522
|
+
##### `#attachment_count`
|
523
|
+
|
524
|
+
Get the number of attachments.
|
525
|
+
|
526
|
+
**Returns:** Integer
|
527
|
+
|
528
|
+
**Example:**
|
529
|
+
|
530
|
+
```ruby
|
531
|
+
puts "Attachments: #{template.attachment_count}"
|
532
|
+
```
|
533
|
+
|
534
|
+
#### Usage Examples
|
535
|
+
|
536
|
+
##### Create a Template
|
537
|
+
|
538
|
+
```ruby
|
539
|
+
template = Gophish::Template.new(
|
540
|
+
name: "Phishing Test Template",
|
541
|
+
subject: "Important Security Update",
|
542
|
+
html: "<h1>Security Update Required</h1><p>Please click <a href='{{.URL}}'>here</a> to update.</p>",
|
543
|
+
text: "Security Update Required\n\nPlease visit {{.URL}} to update your credentials."
|
544
|
+
)
|
545
|
+
|
546
|
+
if template.save
|
547
|
+
puts "Template created with ID: #{template.id}"
|
548
|
+
end
|
549
|
+
```
|
550
|
+
|
551
|
+
##### Template with Attachments
|
552
|
+
|
553
|
+
```ruby
|
554
|
+
template = Gophish::Template.new(
|
555
|
+
name: "Invoice Template",
|
556
|
+
subject: "Invoice #{{.RId}}",
|
557
|
+
html: "<p>Please find your invoice attached.</p>"
|
558
|
+
)
|
559
|
+
|
560
|
+
# Add PDF attachment
|
561
|
+
pdf_content = File.read("invoice.pdf")
|
562
|
+
template.add_attachment(pdf_content, "application/pdf", "invoice.pdf")
|
563
|
+
|
564
|
+
# Add image attachment
|
565
|
+
image_content = File.read("logo.png")
|
566
|
+
template.add_attachment(image_content, "image/png", "logo.png")
|
567
|
+
|
568
|
+
template.save
|
569
|
+
```
|
570
|
+
|
571
|
+
##### Import from Email
|
572
|
+
|
573
|
+
```ruby
|
574
|
+
# Import existing email
|
575
|
+
email_content = File.read("phishing_template.eml")
|
576
|
+
imported_data = Gophish::Template.import_email(
|
577
|
+
email_content,
|
578
|
+
convert_links: true # Convert links for tracking
|
579
|
+
)
|
580
|
+
|
581
|
+
template = Gophish::Template.new(imported_data)
|
582
|
+
template.name = "Imported Phishing Template"
|
583
|
+
template.save
|
584
|
+
```
|
585
|
+
|
586
|
+
##### Update Template
|
587
|
+
|
588
|
+
```ruby
|
589
|
+
template = Gophish::Template.find(1)
|
590
|
+
template.subject = "Updated Subject"
|
591
|
+
template.html = "<h1>Updated Content</h1>"
|
592
|
+
|
593
|
+
# Add new attachment
|
594
|
+
template.add_attachment(File.read("new_doc.pdf"), "application/pdf", "new_doc.pdf")
|
595
|
+
|
596
|
+
# Remove old attachment
|
597
|
+
template.remove_attachment("old_doc.pdf")
|
598
|
+
|
599
|
+
template.save
|
600
|
+
```
|
601
|
+
|
602
|
+
##### Template Validation
|
603
|
+
|
604
|
+
```ruby
|
605
|
+
# Invalid template (no content)
|
606
|
+
template = Gophish::Template.new(name: "Test Template")
|
607
|
+
|
608
|
+
unless template.valid?
|
609
|
+
puts "Validation errors:"
|
610
|
+
template.errors.full_messages.each { |msg| puts " - #{msg}" }
|
611
|
+
# => ["Need to specify at least plaintext or HTML content"]
|
612
|
+
end
|
613
|
+
|
614
|
+
# Invalid attachment
|
615
|
+
template = Gophish::Template.new(
|
616
|
+
name: "Test",
|
617
|
+
html: "<p>Test</p>",
|
618
|
+
attachments: [{ name: "file.pdf" }] # Missing content and type
|
619
|
+
)
|
620
|
+
|
621
|
+
unless template.valid?
|
622
|
+
puts template.errors.full_messages
|
623
|
+
# => ["Attachments item at index 0 must have a content",
|
624
|
+
# "Attachments item at index 0 must have a type"]
|
625
|
+
end
|
626
|
+
```
|
627
|
+
|
628
|
+
## Page Class
|
629
|
+
|
630
|
+
The `Gophish::Page` class represents a landing page in Gophish campaigns.
|
631
|
+
|
632
|
+
### Class: `Gophish::Page < Gophish::Base`
|
633
|
+
|
634
|
+
#### Attributes
|
635
|
+
|
636
|
+
| Attribute | Type | Required | Description |
|
637
|
+
|-----------|------|----------|-------------|
|
638
|
+
| `id` | Integer | No | Unique page identifier (set by server) |
|
639
|
+
| `name` | String | Yes | Page name |
|
640
|
+
| `html` | String | Yes | HTML content of the page |
|
641
|
+
| `capture_credentials` | Boolean | No | Whether to capture credentials (default: false) |
|
642
|
+
| `capture_passwords` | Boolean | No | Whether to capture passwords (default: false) |
|
643
|
+
| `redirect_url` | String | No | URL to redirect users after form submission |
|
644
|
+
| `modified_date` | String | No | Last modification timestamp (set by server) |
|
645
|
+
|
646
|
+
#### Validations
|
647
|
+
|
648
|
+
- `name` must be present
|
649
|
+
- `html` must be present
|
650
|
+
|
651
|
+
#### Class Methods
|
652
|
+
|
653
|
+
##### `.import_site(url, include_resources: false)`
|
654
|
+
|
655
|
+
Import a website as a landing page template.
|
656
|
+
|
657
|
+
**Parameters:**
|
658
|
+
|
659
|
+
- `url` (String) - URL of the website to import
|
660
|
+
- `include_resources` (Boolean) - Whether to include CSS, JS, and images (default: false)
|
661
|
+
|
662
|
+
**Returns:** Hash of page attributes
|
663
|
+
|
664
|
+
**Raises:**
|
665
|
+
|
666
|
+
- `StandardError` if import fails
|
667
|
+
|
668
|
+
**Example:**
|
669
|
+
|
670
|
+
```ruby
|
671
|
+
begin
|
672
|
+
page_data = Gophish::Page.import_site(
|
673
|
+
"https://login.microsoft.com",
|
674
|
+
include_resources: true
|
675
|
+
)
|
676
|
+
|
677
|
+
page = Gophish::Page.new(page_data)
|
678
|
+
page.name = "Imported Microsoft Login"
|
679
|
+
page.capture_credentials = true
|
680
|
+
page.save
|
681
|
+
rescue StandardError => e
|
682
|
+
puts "Import failed: #{e.message}"
|
683
|
+
end
|
684
|
+
```
|
685
|
+
|
686
|
+
#### Instance Methods
|
687
|
+
|
688
|
+
##### `#captures_credentials?`
|
689
|
+
|
690
|
+
Check if page is configured to capture credentials.
|
691
|
+
|
692
|
+
**Returns:** Boolean
|
693
|
+
|
694
|
+
**Example:**
|
695
|
+
|
696
|
+
```ruby
|
697
|
+
page = Gophish::Page.new(capture_credentials: true)
|
698
|
+
puts page.captures_credentials? # => true
|
699
|
+
```
|
700
|
+
|
701
|
+
##### `#captures_passwords?`
|
702
|
+
|
703
|
+
Check if page is configured to capture passwords.
|
704
|
+
|
705
|
+
**Returns:** Boolean
|
706
|
+
|
707
|
+
**Example:**
|
708
|
+
|
709
|
+
```ruby
|
710
|
+
page = Gophish::Page.new(capture_passwords: true)
|
711
|
+
puts page.captures_passwords? # => true
|
712
|
+
```
|
713
|
+
|
714
|
+
##### `#has_redirect?`
|
715
|
+
|
716
|
+
Check if page has a redirect URL configured.
|
717
|
+
|
718
|
+
**Returns:** Boolean
|
719
|
+
|
720
|
+
**Example:**
|
721
|
+
|
722
|
+
```ruby
|
723
|
+
page = Gophish::Page.new(redirect_url: "https://example.com")
|
724
|
+
puts page.has_redirect? # => true
|
725
|
+
|
726
|
+
page = Gophish::Page.new
|
727
|
+
puts page.has_redirect? # => false
|
728
|
+
```
|
729
|
+
|
730
|
+
#### Usage Examples
|
731
|
+
|
732
|
+
##### Create a Basic Landing Page
|
733
|
+
|
734
|
+
```ruby
|
735
|
+
page = Gophish::Page.new(
|
736
|
+
name: "Microsoft Login Clone",
|
737
|
+
html: <<~HTML
|
738
|
+
<!DOCTYPE html>
|
739
|
+
<html>
|
740
|
+
<head>
|
741
|
+
<title>Microsoft Account</title>
|
742
|
+
<style>
|
743
|
+
body {
|
744
|
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
745
|
+
background-color: #f5f5f5;
|
746
|
+
margin: 0;
|
747
|
+
padding: 40px;
|
748
|
+
}
|
749
|
+
.login-form {
|
750
|
+
max-width: 400px;
|
751
|
+
margin: 0 auto;
|
752
|
+
background: white;
|
753
|
+
padding: 40px;
|
754
|
+
border-radius: 8px;
|
755
|
+
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
756
|
+
}
|
757
|
+
.form-group { margin-bottom: 20px; }
|
758
|
+
input {
|
759
|
+
width: 100%;
|
760
|
+
padding: 12px;
|
761
|
+
border: 1px solid #ddd;
|
762
|
+
border-radius: 4px;
|
763
|
+
font-size: 14px;
|
764
|
+
}
|
765
|
+
button {
|
766
|
+
width: 100%;
|
767
|
+
padding: 12px;
|
768
|
+
background: #0078d4;
|
769
|
+
color: white;
|
770
|
+
border: none;
|
771
|
+
border-radius: 4px;
|
772
|
+
font-size: 14px;
|
773
|
+
cursor: pointer;
|
774
|
+
}
|
775
|
+
button:hover { background: #106ebe; }
|
776
|
+
</style>
|
777
|
+
</head>
|
778
|
+
<body>
|
779
|
+
<div class="login-form">
|
780
|
+
<h2>Sign in</h2>
|
781
|
+
<form method="post">
|
782
|
+
<div class="form-group">
|
783
|
+
<input type="email" name="username" placeholder="Email" required>
|
784
|
+
</div>
|
785
|
+
<div class="form-group">
|
786
|
+
<input type="password" name="password" placeholder="Password" required>
|
787
|
+
</div>
|
788
|
+
<button type="submit">Sign in</button>
|
789
|
+
</form>
|
790
|
+
</div>
|
791
|
+
</body>
|
792
|
+
</html>
|
793
|
+
HTML
|
794
|
+
)
|
795
|
+
|
796
|
+
if page.save
|
797
|
+
puts "Landing page created with ID: #{page.id}"
|
798
|
+
end
|
799
|
+
```
|
800
|
+
|
801
|
+
##### Create Page with Credential Capture
|
802
|
+
|
803
|
+
```ruby
|
804
|
+
page = Gophish::Page.new(
|
805
|
+
name: "Banking Portal - Credential Capture",
|
806
|
+
html: <<~HTML
|
807
|
+
<html>
|
808
|
+
<head>
|
809
|
+
<title>Secure Banking Portal</title>
|
810
|
+
<style>
|
811
|
+
body { font-family: Arial, sans-serif; background: #1e3d59; color: white; }
|
812
|
+
.container { max-width: 400px; margin: 100px auto; padding: 40px; background: white; color: black; border-radius: 10px; }
|
813
|
+
input { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #ccc; }
|
814
|
+
button { width: 100%; padding: 12px; background: #1e3d59; color: white; border: none; border-radius: 5px; }
|
815
|
+
</style>
|
816
|
+
</head>
|
817
|
+
<body>
|
818
|
+
<div class="container">
|
819
|
+
<h2>Secure Login</h2>
|
820
|
+
<form method="post">
|
821
|
+
<input type="text" name="username" placeholder="Username" required>
|
822
|
+
<input type="password" name="password" placeholder="Password" required>
|
823
|
+
<button type="submit">Access Account</button>
|
824
|
+
</form>
|
825
|
+
</div>
|
826
|
+
</body>
|
827
|
+
</html>
|
828
|
+
HTML,
|
829
|
+
capture_credentials: true,
|
830
|
+
capture_passwords: true,
|
831
|
+
redirect_url: "https://www.realbank.com/login"
|
832
|
+
)
|
833
|
+
|
834
|
+
puts "Page captures credentials: #{page.captures_credentials?}"
|
835
|
+
puts "Page captures passwords: #{page.captures_passwords?}"
|
836
|
+
puts "Page has redirect: #{page.has_redirect?}"
|
837
|
+
|
838
|
+
page.save
|
839
|
+
```
|
840
|
+
|
841
|
+
##### Import Website as Landing Page
|
842
|
+
|
843
|
+
```ruby
|
844
|
+
# Import a real website
|
845
|
+
begin
|
846
|
+
imported_data = Gophish::Page.import_site(
|
847
|
+
"https://accounts.google.com/signin",
|
848
|
+
include_resources: true # Include CSS, JS, images
|
849
|
+
)
|
850
|
+
|
851
|
+
page = Gophish::Page.new(imported_data)
|
852
|
+
page.name = "Google Login Clone"
|
853
|
+
page.capture_credentials = true
|
854
|
+
|
855
|
+
if page.save
|
856
|
+
puts "Successfully imported Google login page"
|
857
|
+
puts "Page ID: #{page.id}"
|
858
|
+
end
|
859
|
+
|
860
|
+
rescue StandardError => e
|
861
|
+
puts "Failed to import site: #{e.message}"
|
862
|
+
|
863
|
+
# Fallback to manual creation
|
864
|
+
page = Gophish::Page.new(
|
865
|
+
name: "Manual Google Login Clone",
|
866
|
+
html: "<html><body><h1>Google</h1><form method='post'><input name='email' type='email' placeholder='Email'><input name='password' type='password' placeholder='Password'><button type='submit'>Sign in</button></form></body></html>",
|
867
|
+
capture_credentials: true
|
868
|
+
)
|
869
|
+
page.save
|
870
|
+
end
|
871
|
+
```
|
872
|
+
|
873
|
+
##### Update Existing Page
|
874
|
+
|
875
|
+
```ruby
|
876
|
+
page = Gophish::Page.find(1)
|
877
|
+
|
878
|
+
# Update content
|
879
|
+
page.html = page.html.gsub("Sign in", "Login")
|
880
|
+
|
881
|
+
# Enable credential capture
|
882
|
+
page.capture_credentials = true
|
883
|
+
page.capture_passwords = true
|
884
|
+
|
885
|
+
# Set redirect URL
|
886
|
+
page.redirect_url = "https://legitimate-site.com"
|
887
|
+
|
888
|
+
if page.save
|
889
|
+
puts "Page updated successfully"
|
890
|
+
puts "Now captures credentials: #{page.captures_credentials?}"
|
891
|
+
end
|
892
|
+
```
|
893
|
+
|
894
|
+
##### Page Validation
|
895
|
+
|
896
|
+
```ruby
|
897
|
+
# Invalid page (missing required fields)
|
898
|
+
page = Gophish::Page.new
|
899
|
+
|
900
|
+
unless page.valid?
|
901
|
+
puts "Validation errors:"
|
902
|
+
page.errors.full_messages.each { |msg| puts " - #{msg}" }
|
903
|
+
# => ["Name can't be blank", "Html can't be blank"]
|
904
|
+
end
|
905
|
+
|
906
|
+
# Valid page
|
907
|
+
page = Gophish::Page.new(
|
908
|
+
name: "Valid Page",
|
909
|
+
html: "<html><body>Content</body></html>"
|
910
|
+
)
|
911
|
+
|
912
|
+
puts page.valid? # => true
|
913
|
+
```
|
914
|
+
|
915
|
+
##### Checking Page Configuration
|
916
|
+
|
917
|
+
```ruby
|
918
|
+
page = Gophish::Page.find(1)
|
919
|
+
|
920
|
+
# Check capabilities
|
921
|
+
if page.captures_credentials?
|
922
|
+
puts "⚠️ This page will capture user credentials"
|
923
|
+
end
|
924
|
+
|
925
|
+
if page.captures_passwords?
|
926
|
+
puts "🔐 This page will capture passwords in plain text"
|
927
|
+
end
|
928
|
+
|
929
|
+
if page.has_redirect?
|
930
|
+
puts "🔄 Users will be redirected to: #{page.redirect_url}"
|
931
|
+
else
|
932
|
+
puts "🛑 Users will see a generic success message"
|
933
|
+
end
|
934
|
+
```
|
935
|
+
|
936
|
+
##### Delete Page
|
937
|
+
|
938
|
+
```ruby
|
939
|
+
page = Gophish::Page.find(1)
|
940
|
+
|
941
|
+
if page.destroy
|
942
|
+
puts "Page deleted successfully"
|
943
|
+
puts "Page frozen: #{page.frozen?}" # => true
|
944
|
+
end
|
945
|
+
```
|
946
|
+
|
379
947
|
## Error Handling
|
380
948
|
|
381
949
|
### Validation Errors
|