├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── 18344CF4-87B8-4EAC-960F-0424188DBD78.png
├── 328256C3-89CB-4454-91D1-8A35107A23EB.png
├── C416DACE-0F76-4BF9-A84C-D9B5497B1B00.png
├── D4820948-B40E-4B36-BD86-21E6BFDB7FF8.png
├── LICENSE.md
├── README.md
├── icon.png
├── info.plist
├── media
├── bluetooth.png
├── dns-used.png
├── dns.png
├── ethernet.png
├── network.png
├── vpn-connected.png
├── vpn.png
├── wifi-1.png
├── wifi-2.png
├── wifi-3.png
├── wifi-4.png
├── wifi-active-1.png
├── wifi-active-2.png
├── wifi-active-3.png
├── wifi-active-4.png
├── wifi-error-4.png
├── wifi-lock-1.png
├── wifi-lock-2.png
├── wifi-lock-3.png
├── wifi-lock-4.png
├── wifi-star-1.png
├── wifi-star-2.png
├── wifi-star-3.png
└── wifi-star-4.png
├── screenshots
├── wifi-preview.png
└── wifilist-preview.png
├── src
├── ap.sh
├── default-dns.conf
├── dns.sh
├── ethernet.sh
├── ethernetCommon.sh
├── helpers.sh
├── media.sh
├── vpn.sh
├── wifi.sh
├── wifiCommon.sh
└── workflowHandler.sh
└── tests
├── apTests.bats
├── dnsTests.bats
├── ethernetTests.bats
├── variables.bash
├── vpnTests.bats
└── wifiTests.bats
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | test:
7 | runs-on: macos-latest
8 |
9 | steps:
10 | - name: Checkout
11 | uses: actions/checkout@v1
12 |
13 | - name: Install bats
14 | run: brew install bats-core
15 |
16 | - name: Test
17 | run: bats --tap tests
18 |
19 | build:
20 | runs-on: ubuntu-latest
21 | needs: [test]
22 |
23 | steps:
24 | - name: Checkout
25 | uses: actions/checkout@v1
26 |
27 | - name: Build Alfred Workflow
28 | uses: mperezi/build-alfred-workflow@v1
29 | id: alfred_builder
30 | with:
31 | workflow_dir: "."
32 | exclude_patterns: ".git/* .github/* .gitignore"
33 |
34 | - name: Rename
35 | run: mv ${{ steps.alfred_builder.outputs.workflow_file }} Network.alfredworkflow
36 |
37 | - name: Upload Artifact
38 | uses: actions/upload-artifact@v1
39 | with:
40 | name: Network.alfredworkflow
41 | path: Network.alfredworkflow
42 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | todo.md
3 | temp
4 | .DS_Store
5 |
--------------------------------------------------------------------------------
/18344CF4-87B8-4EAC-960F-0424188DBD78.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/18344CF4-87B8-4EAC-960F-0424188DBD78.png
--------------------------------------------------------------------------------
/328256C3-89CB-4454-91D1-8A35107A23EB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/328256C3-89CB-4454-91D1-8A35107A23EB.png
--------------------------------------------------------------------------------
/C416DACE-0F76-4BF9-A84C-D9B5497B1B00.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/C416DACE-0F76-4BF9-A84C-D9B5497B1B00.png
--------------------------------------------------------------------------------
/D4820948-B40E-4B36-BD86-21E6BFDB7FF8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/D4820948-B40E-4B36-BD86-21E6BFDB7FF8.png
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016 Martin Rodalgaard
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #
Alfred Network Workflow 
2 |
3 | Alfred workflow that can show and change your network settings: Wi-Fi, Ethernet, VPN, DNS, etc.
4 |
5 | This is a collection of the functionalities of already existing network-oriented workflows that I found half-baked or stalled. Improved on performance, usability and details.
6 |
7 | ## Install
8 |
9 | Go to [Latest Release](https://github.com/mrodalgaard/alfred-network-workflow/releases/latest) and under `Assets` download `Network.alfredworkflow`. Once downloaded, double click the file and it will show up in Alfred.
10 |
11 | Or install directly from [Alfred Gallery](https://alfred.app/workflows/mrodalgaard/network/).
12 |
13 | ## Usage
14 |
15 | * Type `wifi` to show Wi-Fi info and enable/disable.
16 | * Type `eth` to show ethernet info (if connected).
17 | * Type `wifilist` to scan for Wi-Fi hotspots.
18 | * Type `vpn` to list configured VPNs and connect.
19 | * Type `dns` to list and change DNS settings for primary connection.
20 |
21 |
22 |
23 |
24 |
25 |
26 | ## Limitations
27 |
28 | Requires Alfred Powerpack to install this extension.
29 |
30 | This workflow might behave differently on macOS versions older than 10.7 Lion. This workflow is primarily implemented in Bash interacting with macOS network cli utils (like `networksetup`, `scutil` and `airport`) with a little help from AppleScript.
31 |
32 | Most functionality of this workflow will work without your user being administrator on your machine (see if your user is set as `Admin` or `Standard` in "System Settings.app" -> "Users & Groups"), but actions which changes network settings might fail if you are only a standard user.
33 |
34 | WIFI / Access Point changes requires your keychain password which is a known limitation [Read more](https://github.com/mrodalgaard/alfred-network-workflow/issues/11#issuecomment-559252188).
35 |
36 | ## Tests
37 |
38 | [bats](https://github.com/bats-core/bats-core) is used for automatic testing of Bash functionality. Install with `brew install bats-core` using [brew](http://brew.sh/).
39 |
40 | Run tests: `bats tests`
41 |
42 | ## Credits
43 |
44 | > Contributions, bug reports and feature requests are very welcome.
45 |
46 | > _- Martin_
47 |
--------------------------------------------------------------------------------
/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/icon.png
--------------------------------------------------------------------------------
/info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | bundleid
6 | dk.rodalgaard.alfred.network
7 | category
8 | Tools
9 | connections
10 |
11 | 18344CF4-87B8-4EAC-960F-0424188DBD78
12 |
13 |
14 | destinationuid
15 | 709DCCB5-61D3-4693-8C39-F0A34FA8F6AD
16 | modifiers
17 | 0
18 | modifiersubtext
19 |
20 | vitoclose
21 |
22 |
23 |
24 | 306C666D-40A5-42F2-A4A0-776B168E7799
25 |
26 | 328256C3-89CB-4454-91D1-8A35107A23EB
27 |
28 |
29 | destinationuid
30 | E94FF980-5C9E-41B4-862B-30C04F904070
31 | modifiers
32 | 0
33 | modifiersubtext
34 |
35 | vitoclose
36 |
37 |
38 |
39 | 4C74C452-E821-4F45-9B74-F0C28889BA4F
40 |
41 |
42 | destinationuid
43 | C8DB69EA-BBA7-41E9-B60C-CF315A5F1CAD
44 | modifiers
45 | 0
46 | modifiersubtext
47 |
48 | vitoclose
49 |
50 |
51 |
52 | 709DCCB5-61D3-4693-8C39-F0A34FA8F6AD
53 |
54 |
55 | destinationuid
56 | E675530B-3605-4460-8074-3122E0461D9D
57 | modifiers
58 | 0
59 | modifiersubtext
60 |
61 | vitoclose
62 |
63 |
64 |
65 | 82D72C1A-0B33-483F-AA5E-E25B02CC7971
66 |
67 | C416DACE-0F76-4BF9-A84C-D9B5497B1B00
68 |
69 |
70 | destinationuid
71 | 306C666D-40A5-42F2-A4A0-776B168E7799
72 | modifiers
73 | 0
74 | modifiersubtext
75 |
76 | vitoclose
77 |
78 |
79 |
80 | C8DB69EA-BBA7-41E9-B60C-CF315A5F1CAD
81 |
82 | D4820948-B40E-4B36-BD86-21E6BFDB7FF8
83 |
84 |
85 | destinationuid
86 | 82D72C1A-0B33-483F-AA5E-E25B02CC7971
87 | modifiers
88 | 0
89 | modifiersubtext
90 |
91 | vitoclose
92 |
93 |
94 |
95 | E94FF980-5C9E-41B4-862B-30C04F904070
96 |
97 |
98 | destinationuid
99 | E675530B-3605-4460-8074-3122E0461D9D
100 | modifiers
101 | 0
102 | modifiersubtext
103 |
104 | vitoclose
105 |
106 |
107 |
108 |
109 | createdby
110 | Martin Rodalgaard
111 | description
112 | Show and change your network settings
113 | disabled
114 |
115 | name
116 | Network
117 | objects
118 |
119 |
120 | config
121 |
122 | alfredfiltersresults
123 |
124 | alfredfiltersresultsmatchmode
125 | 0
126 | argumenttreatemptyqueryasnil
127 |
128 | argumenttrimmode
129 | 0
130 | argumenttype
131 | 2
132 | escaping
133 | 102
134 | keyword
135 | wifi
136 | queuedelaycustom
137 | 3
138 | queuedelayimmediatelyinitially
139 |
140 | queuedelaymode
141 | 0
142 | queuemode
143 | 1
144 | runningsubtext
145 | Fetching wifi information ...
146 | script
147 | . src/wifi.sh
148 | scriptargtype
149 | 0
150 | scriptfile
151 |
152 | subtext
153 | Wi-Fi info
154 | title
155 | Wi-Fi
156 | type
157 | 0
158 | withspace
159 |
160 |
161 | type
162 | alfred.workflow.input.scriptfilter
163 | uid
164 | 328256C3-89CB-4454-91D1-8A35107A23EB
165 | version
166 | 3
167 |
168 |
169 | config
170 |
171 | concurrently
172 |
173 | escaping
174 | 102
175 | script
176 | . src/wifi.sh "{query}"
177 | scriptargtype
178 | 0
179 | scriptfile
180 |
181 | type
182 | 0
183 |
184 | type
185 | alfred.workflow.action.script
186 | uid
187 | E94FF980-5C9E-41B4-862B-30C04F904070
188 | version
189 | 2
190 |
191 |
192 | config
193 |
194 | autopaste
195 |
196 | clipboardtext
197 | {query}
198 | ignoredynamicplaceholders
199 |
200 | transient
201 |
202 |
203 | type
204 | alfred.workflow.output.clipboard
205 | uid
206 | E675530B-3605-4460-8074-3122E0461D9D
207 | version
208 | 3
209 |
210 |
211 | config
212 |
213 | alfredfiltersresults
214 |
215 | alfredfiltersresultsmatchmode
216 | 0
217 | argumenttreatemptyqueryasnil
218 |
219 | argumenttrimmode
220 | 0
221 | argumenttype
222 | 2
223 | escaping
224 | 102
225 | keyword
226 | eth
227 | queuedelaycustom
228 | 3
229 | queuedelayimmediatelyinitially
230 |
231 | queuedelaymode
232 | 0
233 | queuemode
234 | 1
235 | runningsubtext
236 | Fetching ethernet information ...
237 | script
238 | . src/ethernet.sh
239 | scriptargtype
240 | 0
241 | scriptfile
242 |
243 | subtext
244 | Ethernet Info
245 | title
246 | Ethernet
247 | type
248 | 0
249 | withspace
250 |
251 |
252 | type
253 | alfred.workflow.input.scriptfilter
254 | uid
255 | 18344CF4-87B8-4EAC-960F-0424188DBD78
256 | version
257 | 3
258 |
259 |
260 | config
261 |
262 | concurrently
263 |
264 | escaping
265 | 102
266 | script
267 | . src/ethernet.sh "{query}"
268 | scriptargtype
269 | 0
270 | scriptfile
271 |
272 | type
273 | 0
274 |
275 | type
276 | alfred.workflow.action.script
277 | uid
278 | 709DCCB5-61D3-4693-8C39-F0A34FA8F6AD
279 | version
280 | 2
281 |
282 |
283 | config
284 |
285 | concurrently
286 |
287 | escaping
288 | 102
289 | script
290 | . src/ap.sh "{query}"
291 | scriptargtype
292 | 0
293 | scriptfile
294 |
295 | type
296 | 0
297 |
298 | type
299 | alfred.workflow.action.script
300 | uid
301 | C8DB69EA-BBA7-41E9-B60C-CF315A5F1CAD
302 | version
303 | 2
304 |
305 |
306 | config
307 |
308 | alfredfiltersresults
309 |
310 | alfredfiltersresultsmatchmode
311 | 2
312 | argumenttreatemptyqueryasnil
313 |
314 | argumenttrimmode
315 | 0
316 | argumenttype
317 | 1
318 | escaping
319 | 102
320 | keyword
321 | wifilist
322 | queuedelaycustom
323 | 3
324 | queuedelayimmediatelyinitially
325 |
326 | queuedelaymode
327 | 0
328 | queuemode
329 | 1
330 | runningsubtext
331 | Scanning for access points ...
332 | script
333 | . src/ap.sh
334 | scriptargtype
335 | 0
336 | scriptfile
337 |
338 | subtext
339 | List of Wi-Fi access points
340 | title
341 | Wi-Fi List
342 | type
343 | 0
344 | withspace
345 |
346 |
347 | type
348 | alfred.workflow.input.scriptfilter
349 | uid
350 | 4C74C452-E821-4F45-9B74-F0C28889BA4F
351 | version
352 | 3
353 |
354 |
355 | config
356 |
357 | concurrently
358 |
359 | escaping
360 | 68
361 | script
362 | . src/vpn.sh "{query}"
363 | scriptargtype
364 | 0
365 | scriptfile
366 |
367 | type
368 | 0
369 |
370 | type
371 | alfred.workflow.action.script
372 | uid
373 | 306C666D-40A5-42F2-A4A0-776B168E7799
374 | version
375 | 2
376 |
377 |
378 | config
379 |
380 | alfredfiltersresults
381 |
382 | alfredfiltersresultsmatchmode
383 | 2
384 | argumenttreatemptyqueryasnil
385 |
386 | argumenttrimmode
387 | 0
388 | argumenttype
389 | 1
390 | escaping
391 | 102
392 | keyword
393 | vpn
394 | queuedelaycustom
395 | 3
396 | queuedelayimmediatelyinitially
397 |
398 | queuedelaymode
399 | 0
400 | queuemode
401 | 1
402 | runningsubtext
403 | Fetching VPN list ...
404 | script
405 | . src/vpn.sh
406 | scriptargtype
407 | 0
408 | scriptfile
409 |
410 | subtext
411 | List of VPNs
412 | title
413 | VPN List
414 | type
415 | 0
416 | withspace
417 |
418 |
419 | type
420 | alfred.workflow.input.scriptfilter
421 | uid
422 | C416DACE-0F76-4BF9-A84C-D9B5497B1B00
423 | version
424 | 3
425 |
426 |
427 | config
428 |
429 | concurrently
430 |
431 | escaping
432 | 102
433 | script
434 | . src/dns.sh "{query}"
435 | scriptargtype
436 | 0
437 | scriptfile
438 |
439 | type
440 | 0
441 |
442 | type
443 | alfred.workflow.action.script
444 | uid
445 | 82D72C1A-0B33-483F-AA5E-E25B02CC7971
446 | version
447 | 2
448 |
449 |
450 | config
451 |
452 | alfredfiltersresults
453 |
454 | alfredfiltersresultsmatchmode
455 | 2
456 | argumenttreatemptyqueryasnil
457 |
458 | argumenttrimmode
459 | 0
460 | argumenttype
461 | 1
462 | escaping
463 | 102
464 | keyword
465 | dns
466 | queuedelaycustom
467 | 3
468 | queuedelayimmediatelyinitially
469 |
470 | queuedelaymode
471 | 0
472 | queuemode
473 | 1
474 | runningsubtext
475 | Fetching DNS list ...
476 | script
477 | . src/dns.sh
478 | scriptargtype
479 | 0
480 | scriptfile
481 |
482 | subtext
483 | List of DNS
484 | title
485 | DNS List
486 | type
487 | 0
488 | withspace
489 |
490 |
491 | type
492 | alfred.workflow.input.scriptfilter
493 | uid
494 | D4820948-B40E-4B36-BD86-21E6BFDB7FF8
495 | version
496 | 3
497 |
498 |
499 | readme
500 | https://github.com/mrodalgaard/alfred-network-workflow
501 | uidata
502 |
503 | 18344CF4-87B8-4EAC-960F-0424188DBD78
504 |
505 | xpos
506 | 30
507 | ypos
508 | 140
509 |
510 | 306C666D-40A5-42F2-A4A0-776B168E7799
511 |
512 | xpos
513 | 230
514 | ypos
515 | 380
516 |
517 | 328256C3-89CB-4454-91D1-8A35107A23EB
518 |
519 | xpos
520 | 30
521 | ypos
522 | 20
523 |
524 | 4C74C452-E821-4F45-9B74-F0C28889BA4F
525 |
526 | xpos
527 | 30
528 | ypos
529 | 260
530 |
531 | 709DCCB5-61D3-4693-8C39-F0A34FA8F6AD
532 |
533 | xpos
534 | 230
535 | ypos
536 | 140
537 |
538 | 82D72C1A-0B33-483F-AA5E-E25B02CC7971
539 |
540 | xpos
541 | 230
542 | ypos
543 | 500
544 |
545 | C416DACE-0F76-4BF9-A84C-D9B5497B1B00
546 |
547 | xpos
548 | 30
549 | ypos
550 | 380
551 |
552 | C8DB69EA-BBA7-41E9-B60C-CF315A5F1CAD
553 |
554 | xpos
555 | 230
556 | ypos
557 | 260
558 |
559 | D4820948-B40E-4B36-BD86-21E6BFDB7FF8
560 |
561 | xpos
562 | 30
563 | ypos
564 | 500
565 |
566 | E675530B-3605-4460-8074-3122E0461D9D
567 |
568 | xpos
569 | 510
570 | ypos
571 | 20
572 |
573 | E94FF980-5C9E-41B4-862B-30C04F904070
574 |
575 | xpos
576 | 230
577 | ypos
578 | 20
579 |
580 |
581 | userconfigurationconfig
582 |
583 | version
584 | 1.7
585 | webaddress
586 | https://github.com/mrodalgaard/alfred-network-workflow
587 |
588 |
589 |
--------------------------------------------------------------------------------
/media/bluetooth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/bluetooth.png
--------------------------------------------------------------------------------
/media/dns-used.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/dns-used.png
--------------------------------------------------------------------------------
/media/dns.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/dns.png
--------------------------------------------------------------------------------
/media/ethernet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/ethernet.png
--------------------------------------------------------------------------------
/media/network.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/network.png
--------------------------------------------------------------------------------
/media/vpn-connected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/vpn-connected.png
--------------------------------------------------------------------------------
/media/vpn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/vpn.png
--------------------------------------------------------------------------------
/media/wifi-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/wifi-1.png
--------------------------------------------------------------------------------
/media/wifi-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/wifi-2.png
--------------------------------------------------------------------------------
/media/wifi-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/wifi-3.png
--------------------------------------------------------------------------------
/media/wifi-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/wifi-4.png
--------------------------------------------------------------------------------
/media/wifi-active-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/wifi-active-1.png
--------------------------------------------------------------------------------
/media/wifi-active-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/wifi-active-2.png
--------------------------------------------------------------------------------
/media/wifi-active-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/wifi-active-3.png
--------------------------------------------------------------------------------
/media/wifi-active-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/wifi-active-4.png
--------------------------------------------------------------------------------
/media/wifi-error-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/wifi-error-4.png
--------------------------------------------------------------------------------
/media/wifi-lock-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/wifi-lock-1.png
--------------------------------------------------------------------------------
/media/wifi-lock-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/wifi-lock-2.png
--------------------------------------------------------------------------------
/media/wifi-lock-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/wifi-lock-3.png
--------------------------------------------------------------------------------
/media/wifi-lock-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/wifi-lock-4.png
--------------------------------------------------------------------------------
/media/wifi-star-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/wifi-star-1.png
--------------------------------------------------------------------------------
/media/wifi-star-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/wifi-star-2.png
--------------------------------------------------------------------------------
/media/wifi-star-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/wifi-star-3.png
--------------------------------------------------------------------------------
/media/wifi-star-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/media/wifi-star-4.png
--------------------------------------------------------------------------------
/screenshots/wifi-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/screenshots/wifi-preview.png
--------------------------------------------------------------------------------
/screenshots/wifilist-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrodalgaard/alfred-network-workflow/0c1beda36a0d38dd7145c251439e76ed4c951a87/screenshots/wifilist-preview.png
--------------------------------------------------------------------------------
/src/ap.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . src/wifiCommon.sh
4 | . src/workflowHandler.sh
5 |
6 | # Handle action
7 | if [ "$1" != "" ]; then
8 | if [ "$1" == "Null" ]; then
9 | exit
10 | fi
11 |
12 | # Extract password for AP, which is needed by networksetup
13 | PASS=$(security 2>&1 >/dev/null find-generic-password -ga "$1" \
14 | | awk '/ / {print $2}' | tr -d '"')
15 | networksetup -setairportnetwork "$INTERFACE" "$1" "$PASS"
16 | exit
17 | fi
18 |
19 | INFO=$($AIRPORT --getinfo)
20 | SAVED_APS=$(networksetup -listpreferredwirelessnetworks "$INTERFACE")
21 |
22 | ACTIVE_ID=$(getBSSID "$INFO")
23 | if [ "$ACTIVE_ID" == "" ]; then
24 | ACTIVE_ID=$(getSSID "$INFO")
25 | fi
26 |
27 | # Scan airport access points and remove header
28 | APS=$($AIRPORT --scan | awk 'NR>1')
29 |
30 | if [ "$APS" == "" ]; then
31 | # Handle no wifi access points found
32 | addResult "" "Null" "No access points found" "" "$ICON_WIFI_ERROR"
33 | else
34 | PARSED_APS=''
35 |
36 | # Parse each AP scan line
37 | while read -r LINE; do
38 | PARSED_APS+=$(getAPDetails "$LINE" "$ACTIVE_ID" "$SAVED_APS")$'\n'
39 | done <<< "$APS"
40 |
41 | # Sort parsed access points by priority and name
42 | PARSED_APS=$(echo "$PARSED_APS" | sort)
43 |
44 | # Sort and create workflow results from each line
45 | while read -r LINE; do
46 | IFS='~' read -r -a ARRAY <<< "$LINE"
47 |
48 | if [ "${ARRAY[0]}" != "" ]; then
49 | addResult "" "${ARRAY[1]}" "${ARRAY[1]}" "RSSI ${ARRAY[3]} dBm, channel ${ARRAY[4]}" "${ARRAY[6]}"
50 | fi
51 | done <<< "$PARSED_APS"
52 | fi
53 |
54 | getXMLResults
55 |
--------------------------------------------------------------------------------
/src/default-dns.conf:
--------------------------------------------------------------------------------
1 | #
2 | # @file dns.conf
3 | #
4 | # Alfred Network Workflow
5 | # Custom DNS List
6 | #
7 | # Format:
8 | # :
9 | #
10 |
11 | Google DNS : 8.8.8.8, 8.8.4.4
12 | OpenDNS : 208.67.222.222, 208.67.220.220
13 | Cloudflare DNS: 1.1.1.1, 1.0.0.1
14 | DNS.WATCH : 84.200.69.80, 84.200.70.40
15 | Alibaba DNS : 223.5.5.5, 223.6.6.6
16 | V2EX DNS : 199.91.73.222, 178.79.131.110
17 | 114 DNS : 114.114.114.114, 114.114.115.115
18 |
--------------------------------------------------------------------------------
/src/dns.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . src/helpers.sh
4 |
5 | # Copy defaults to alfred cache dir if they do not exist
6 | FILE=$alfred_workflow_cache/dns.conf
7 | if [ ! -f "$FILE" ]; then
8 | mkdir -p "$alfred_workflow_cache"
9 | cp src/default-dns.conf "$FILE"
10 | fi
11 |
12 | NAME="$(getPrimaryInterfaceName)"
13 |
14 | # Handle action
15 | if [ "$1" != "" ]; then
16 | if [ "$1" == "EDIT" ]; then
17 | open -a TextEdit "$FILE"
18 | exit
19 | elif [ "$1" == "DEFAULT" ]; then
20 | DNS="empty"
21 | else
22 | DNS=$(echo "$1" | sed 's/ \/ / /g')
23 | fi
24 |
25 | networksetup -setdnsservers "${NAME%,*}" $DNS
26 | dscacheutil -flushcache
27 | exit
28 | fi
29 |
30 | DNSSTRING=$(getDNS "$(networksetup -getdnsservers "$NAME")")
31 |
32 | # Parse dns config file
33 | while read -r LINE; do
34 | DNSCONFIG=$(parseDNSLine "$LINE" "$DNSSTRING")
35 | IFS='~' read -r -a ARRAY <<< "$DNSCONFIG"
36 |
37 | if [ "$ARRAY" != "" ]; then
38 | addResult "" "${ARRAY[1]}" "${ARRAY[0]}" "${ARRAY[1]}" "${ARRAY[2]}"
39 | fi
40 | done < "$FILE"
41 |
42 | addResult "" "EDIT" "Edit DNS List" "" "$ICON_DNS"
43 |
44 | if [ "$DNSSTRING" == "" ]; then
45 | addResult "" "DEFAULT" "Default DNS (used)" "Default" "$ICON_DNS_USED"
46 | else
47 | addResult "" "DEFAULT" "Default DNS" "Default" "$ICON_DNS"
48 | fi
49 |
50 | getXMLResults
51 |
--------------------------------------------------------------------------------
/src/ethernet.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . src/ethernetCommon.sh
4 | . src/workflowHandler.sh
5 |
6 | # Handle action
7 | if [ "$1" != "" ]; then
8 | echo "$1" | tr -d '\n'
9 | exit
10 | fi
11 |
12 | # Handle ethernet unconnected state
13 | if [ "$(getEthernetState "$INTERFACE")" == 0 ]; then
14 | addResult "" "" "Not Connected" "Ethernet is not connected" "$ICON_ETH"
15 | getXMLResults
16 | return
17 | fi
18 |
19 | # Get network configuration
20 | NETINFO=$(networksetup -getinfo "$NAME")
21 | NETCONFIG=$(getConnectionConfig "$NETINFO")
22 |
23 | MAC=$(getEthernetMac)
24 | NAME=$(getEthernetName)
25 |
26 | # Output IPv4
27 | IPv4=$(getIPv4 "$NETINFO")
28 | if [[ ! -z "$IPv4" ]]; then
29 | addResult "" "$IPv4" "$IPv4" "IPv4 address ($NETCONFIG)" "$ICON_ETH"
30 | fi
31 |
32 | # Output IPv6
33 | IPv6=$(getIPv6 "$NETINFO")
34 | if [ "$IPv6" != "" ]; then
35 | addResult "" "$IPv6" "$IPv6" "IPv6 address ($NETCONFIG)" "$ICON_ETH"
36 | fi
37 |
38 | # Output global IP
39 | GLOBALIP=$(getGlobalIP)
40 | if [ "$GLOBALIP" != "" ]; then
41 | addResult "" "$GLOBALIP" "$GLOBALIP" "Global IP" "$ICON_ETH"
42 | fi
43 |
44 | # Output VPN
45 | SCUTIL=$(scutil --nc list)
46 | VPN=$(getVPN "$SCUTIL")
47 | if [ "$VPN" != "" ]; then
48 | addResult "" "$VPN" "$VPN" "VPN connection" "$ICON_ETH"
49 | fi
50 |
51 | # Output DNS list
52 | DNSSTRING=$(getDNS "$(networksetup -getdnsservers "$NAME")")
53 | if [ "$DNSSTRING" != "" ]; then
54 | addResult "" "$DNSSTRING" "$DNSSTRING" "DNS list" "$ICON_ETH"
55 | fi
56 |
57 | addResult "" "" "$NAME connected" "$INTERFACE ($MAC)" "$ICON_ETH"
58 |
59 | getXMLResults
60 |
--------------------------------------------------------------------------------
/src/ethernetCommon.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . src/helpers.sh
4 |
5 | LIST=$(networksetup -listallhardwareports)
6 | INTERFACE=$(getEthernetInterface "$LIST")
7 | NAME=$(getEthernetName "$LIST")
8 |
--------------------------------------------------------------------------------
/src/helpers.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . src/workflowHandler.sh
4 | . src/media.sh
5 |
6 | ETHERNET_REGEX="LAN$|Lan$|Ethernet$|AX[0-9A-Z]+$"
7 | WIFI_REGEX="Airport$|Wi-Fi$"
8 |
9 | PRIORITY_HIGH="1"
10 | PRIORITY_MEDIUM="2"
11 | PRIORITY_LOW="5"
12 |
13 | # Trim string
14 | # $1 = Input string
15 | # $! = Trimmed string
16 | trim () {
17 | str="$1"
18 | match=" "
19 | while [ "${str:0:${#match}}" == "$match" ]; do
20 | str="${str:${#match}:${#str}}"
21 | done
22 | while [ "${str:$((${#str}-${#match}))}" == "$match" ]; do
23 | str="${str:0:$((${#str} - ${#match}))}"
24 | done
25 | echo "$str"
26 | }
27 |
28 | # Get wifi state as boolean
29 | # $1 = Wi-Fi interface name
30 | # $! = Boolean
31 | getWifiState() {
32 | if [ "$(networksetup -getairportpower "$1" | grep On)" != "" ]; then
33 | echo 1
34 | else
35 | echo 0
36 | fi
37 | }
38 |
39 | # Get ethernet state as boolean
40 | # $1 = Ethernet interface name
41 | # $! = Boolean
42 | getEthernetState() {
43 | if [ "$1" != "" ]; then
44 | echo 1
45 | else
46 | echo 0
47 | fi
48 | }
49 |
50 | # Get wifi port name
51 | # $1 = networksetup -listallhardwareports
52 | # $! = String
53 | getWifiName() {
54 | local LIST=${1-$(networksetup -listallhardwareports)}
55 | local DETAILS=$(echo "$LIST" | grep -A 2 -E "$WIFI_REGEX")
56 | echo "$DETAILS" | grep -Eo "AirPort|Wi-Fi"
57 | }
58 |
59 | # Get ethernet port name
60 | # $1 = networksetup -listallhardwareports
61 | # $! = String
62 | getEthernetName() {
63 | local LIST=${1-$(networksetup -listallhardwareports)}
64 | local DETAILS=$(echo "$LIST" | grep -A 2 -E "$ETHERNET_REGEX")
65 | echo "$DETAILS" | awk '/Hardware / {print substr($0, index($0, $3))}'
66 | }
67 |
68 | # Get wifi interface name
69 | # $1 = networksetup -listallhardwareports
70 | # $! = String
71 | getWifiInterface() {
72 | local LIST=${1-$(networksetup -listallhardwareports)}
73 | local DETAILS=$(echo "$LIST" | grep -A 2 -E "$WIFI_REGEX")
74 | echo "$DETAILS" | grep -m 1 -o -e en[0-9]
75 | }
76 |
77 | # Get ethernet interface name
78 | # $1 = networksetup -listallhardwareports
79 | # $! = String
80 | getEthernetInterface() {
81 | local LIST=${1-$(networksetup -listallhardwareports)}
82 | local DETAILS=$(echo "$LIST" | grep -A 2 -E "$ETHERNET_REGEX")
83 | echo "$DETAILS" | grep -m 1 -o -e en[0-9]
84 | }
85 |
86 | # Get wifi mac address
87 | # $1 = networksetup -listallhardwareports
88 | # $! = String
89 | getWifiMac() {
90 | local LIST=${1-$(networksetup -listallhardwareports)}
91 | local DETAILS=$(echo "$LIST" | grep -A 2 -E "$WIFI_REGEX")
92 | echo "$DETAILS" | awk '/Ethernet Address: / {print substr($0, index($0, $3))}'
93 | }
94 |
95 | # Get ethernet mac address
96 | # $1 = networksetup -listallhardwareports
97 | # $! = String
98 | getEthernetMac() {
99 | local LIST=${1-$(networksetup -listallhardwareports)}
100 | local DETAILS=$(echo "$LIST" | grep -A 2 -E "$ETHERNET_REGEX")
101 | echo "$DETAILS" | awk '/Ethernet Address: / {print substr($0, index($0, $3))}'
102 | }
103 |
104 | # Find name of primary connected network interface
105 | # $! = String
106 | getPrimaryInterfaceName() {
107 | local INTERFACE=$(getEthernetInterface)
108 | if [ $(getEthernetState "$INTERFACE") != 0 ]; then
109 | echo "$(getEthernetName)"
110 | else
111 | echo "$(getWifiName)"
112 | fi
113 | }
114 |
115 | # Extract connection configuration
116 | # $1 = networksetup -getinfo
117 | # $! = String
118 | getConnectionConfig() {
119 | echo "$1" | grep 'Configuration$'
120 | }
121 |
122 | # Extract IP4
123 | # $1 = networksetup -getinfo
124 | # $! = String
125 | getIPv4() {
126 | echo "$1" | grep '^IP\saddress' \
127 | | awk '/ address/ {print substr($0, index($0, $3))}'
128 | }
129 |
130 | # Extract IP6
131 | # $1 = networksetup -getinfo
132 | # $! = String
133 | getIPv6() {
134 | local IPv6=$(echo "$1" \
135 | | grep '^IPv6 IP address' \
136 | | awk '/ address/ {print substr($0, index($0, $4))}')
137 |
138 | if [ "$IPv6" == "none" ]; then
139 | echo ""
140 | else
141 | echo "$IPv6"
142 | fi
143 | }
144 |
145 | # Extract SSID
146 | # $1 = airport -getinfo
147 | # $! = String
148 | getSSID() {
149 | echo "$1" | awk '/ SSID/ {print substr($0, index($0, $2))}'
150 | }
151 |
152 | # Pad BSSID
153 | # $1 = BSSID string
154 | # $! = String
155 | padBSSID() {
156 | if [ ${#1} == 17 ]; then
157 | echo "$1"
158 | else
159 | for PART in $(echo "$1" | tr ":" "\n"); do
160 | if [ "$skipFirst" != "" ]; then
161 | printf ":"
162 | fi
163 | skipFirst=true
164 | printf "%02s" "$PART"
165 | done
166 | fi
167 | }
168 |
169 | # Get BSSID
170 | # $1 = airport -getinfo
171 | # $! = String
172 | getBSSID() {
173 | local BSSID=$(echo "$1" | awk '/ BSSID/ {print substr($0, index($0, $2))}' | xargs)
174 | # Handle missing BSSID
175 | if [ "$BSSID" == "BSSID:" ]; then
176 | echo ""
177 | else
178 | echo $(padBSSID "$BSSID")
179 | fi
180 | }
181 |
182 | # Extract wifi authentication
183 | # $1 = airport -getinfo
184 | # $! = String
185 | getAuth() {
186 | echo "$1" | awk '/ link auth/ {print substr($0, index($0, $2))}'
187 | }
188 |
189 | # Resolve global IP
190 | # $1 = Dig resolver address (optional)
191 | # $! = String
192 | getGlobalIP() {
193 | local RESOLVER=${1:-"myip.opendns.com @resolver1.opendns.com"}
194 |
195 | local IP=$(dig -4 +time=2 +tries=1 +short $RESOLVER)
196 | if [[ "$IP" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
197 | echo "$IP"
198 | fi
199 | }
200 |
201 | # Get connected VPN
202 | # $1 = scutil --nc list
203 | # $! = String
204 | getVPN() {
205 | echo "$1" | awk '/\/*.(Connected)/ {print $7}' | tr -d '"'
206 | }
207 |
208 | # Get VPN info
209 | # $1 = `scutil --nc list` lines
210 | # $! = Separated string of VPN info
211 | getVPNInfo() {
212 | if [[ "$1" =~ \*[[:space:]]\(([a-zA-Z ]*)\)[[:space:]].*\"(.*)\".*\[(.*)\] ]]
213 | then
214 | STATE=${BASH_REMATCH[1]}
215 | NAME=${BASH_REMATCH[2]}
216 | TYPE=${BASH_REMATCH[3]}
217 | fi
218 |
219 | if [ "$STATE" == "Connected" ]; then
220 | AP_ICON=$ICON_VPN_CONNECTED
221 | else
222 | AP_ICON=$ICON_VPN
223 | fi
224 |
225 | echo "$STATE"~"$NAME"~"$TYPE"~"$AP_ICON"
226 | }
227 |
228 | # Get DNS info
229 | # $1 = `networksetup -getdnsservers `
230 | # $! = String
231 | getDNS() {
232 | if [[ "$1" != *"any DNS"* ]]; then
233 | echo $1 | sed 's/ / \/ /g'
234 | else
235 | echo ""
236 | fi
237 | }
238 |
239 | # Parse DNS info
240 | # $1 = line of dns config file
241 | # $2 = active dns list
242 | # $! = Separated string of dns config elements
243 | parseDNSLine() {
244 | IFS=':' read -r -a ARRAY <<< "$1"
245 | if [[ "${ARRAY[0]}" =~ ^# ]] || [ "${ARRAY[0]}" == "" ] || [ "${ARRAY[1]}" == "" ]; then
246 | return
247 | fi
248 |
249 | local ID=$(trim "${ARRAY[0]}")
250 | local DNS=$(echo "${ARRAY[1]}" | sed 's/ //g' | sed 's/,/ \/ /g')
251 | local ICON=$ICON_DNS
252 |
253 | if [ "$DNS" == "$2" ]; then
254 | ICON=$ICON_DNS_USED
255 | ID="$ID (used)"
256 | fi
257 |
258 | echo "$ID"~"$DNS"~"$ICON"
259 | }
260 |
261 | # Get saved access point
262 | # $1 = networksetup -listpreferredwirelessnetworks
263 | # $! = Separated string of saved access points
264 | getSavedAPs() {
265 | while read -r line; do
266 | OUTPUT=$OUTPUT~$line
267 | done <<< "$1"
268 | echo "${OUTPUT:1}"
269 | }
270 |
271 | # Check if list contains an element
272 | # $1 = List of elements
273 | # $2 = Element to check
274 | # $! = Boolean
275 | listContains() {
276 | while read -r ITEM; do
277 | if [ "$ITEM" == "$2" ]; then
278 | echo 1
279 | fi
280 | done <<< "$1"
281 | }
282 |
283 | # Get WiFi strength
284 | # $1 = Wifi RSSI
285 | # $! = Wifi strength level 1-4
286 | getWifiStrength() {
287 | if [ "$1" -lt -80 ]; then
288 | echo 1
289 | elif [ "$1" -lt -70 ]; then
290 | echo 2
291 | elif [ "$1" -lt -60 ]; then
292 | echo 3
293 | else
294 | echo 4
295 | fi
296 | }
297 |
298 | # Parse access point details string
299 | # $1 = `airpot --scan` line
300 | # $2 = BSSID or SSID of the active access point (optional)
301 | # $3 = List of favorite access points (optional)
302 | # $! = Separated string of access point settings
303 | getAPDetails() {
304 | # Example: SSID BSSID RSSI CHANNEL HT CC SECURITY
305 | # Example: "Test-Network 21:aa:4c:b4:cc:11 -24 6 Y US WPA2(PSK/AES/AES)"
306 | if [[ "$1" =~ [[:space:]]*(.*)[[:space:]]+([0-9a-f:]{17})?[[:space:]]+(-[0-9]{2})[[:space:]]+([,+0-9]+)[[:space:]]+([YN]{1})[[:space:]]+([-A-Z]{2})[[:space:]]+(.*) ]]
307 | then
308 | SSID=$(echo ${BASH_REMATCH[1]} | xargs)
309 | BSSID=${BASH_REMATCH[2]}
310 | RSSI=${BASH_REMATCH[3]}
311 | CHANNEL=${BASH_REMATCH[4]}
312 | HT=${BASH_REMATCH[5]}
313 | CC=${BASH_REMATCH[6]}
314 | SECURITY=$(echo ${BASH_REMATCH[7]} | xargs)
315 | fi
316 |
317 | FAVORITED=$(listContains "$3" "$SSID")
318 | PRIORITY=$PRIORITY_LOW
319 |
320 | if [ "$BSSID" != "" ] && [ "$BSSID" == "$2" ] || [ "$SSID" == "$2" ]; then
321 | AP_ICON=$ICON_WIFI_ACTIVE_
322 | PRIORITY=$PRIORITY_HIGH
323 | elif [ "$FAVORITED" != "" ]; then
324 | AP_ICON=$ICON_WIFI_STAR_
325 | PRIORITY=$PRIORITY_MEDIUM
326 | elif [[ "$SECURITY" =~ "NONE" ]]; then
327 | AP_ICON=$ICON_WIFI_
328 | else
329 | AP_ICON=$ICON_WIFI_LOCK_
330 | fi
331 |
332 | AP_ICON=$AP_ICON$(getWifiStrength "$RSSI")$ICON_END
333 |
334 | if [ "$SSID" != "" ]; then
335 | echo "$PRIORITY"~"$SSID"~"$BSSID"~"$RSSI"~"$CHANNEL"~"$SECURITY"~"$AP_ICON"
336 | fi
337 | }
338 |
--------------------------------------------------------------------------------
/src/media.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ICON_END=".png"
4 |
5 | ICON_WIFI="media/wifi-4.png"
6 | ICON_WIFI_="media/wifi-"
7 | ICON_WIFI_4="media/wifi-4.png"
8 | ICON_WIFI_3="media/wifi-3.png"
9 | ICON_WIFI_2="media/wifi-2.png"
10 | ICON_WIFI_1="media/wifi-1.png"
11 |
12 | ICON_WIFI_LOCK="media/wifi-lock-4.png"
13 | ICON_WIFI_LOCK_="media/wifi-lock-"
14 | ICON_WIFI_LOCK_4="media/wifi-lock-4.png"
15 | ICON_WIFI_LOCK_3="media/wifi-lock-3.png"
16 | ICON_WIFI_LOCK_2="media/wifi-lock-2.png"
17 | ICON_WIFI_LOCK_1="media/wifi-lock-1.png"
18 |
19 | ICON_WIFI_STAR="media/wifi-star-4.png"
20 | ICON_WIFI_STAR_="media/wifi-star-"
21 | ICON_WIFI_STAR_4="media/wifi-star-4.png"
22 | ICON_WIFI_STAR_3="media/wifi-star-3.png"
23 | ICON_WIFI_STAR_2="media/wifi-star-2.png"
24 | ICON_WIFI_STAR_1="media/wifi-star-1.png"
25 |
26 | ICON_WIFI_ACTIVE="media/wifi-active-4.png"
27 | ICON_WIFI_ACTIVE_="media/wifi-active-"
28 | ICON_WIFI_ACTIVE_4="media/wifi-active-4.png"
29 | ICON_WIFI_ACTIVE_3="media/wifi-active-3.png"
30 | ICON_WIFI_ACTIVE_2="media/wifi-active-2.png"
31 | ICON_WIFI_ACTIVE_1="media/wifi-active-1.png"
32 |
33 | ICON_WIFI_ERROR="media/wifi-error-4.png"
34 |
35 | ICON_ETH="media/ethernet.png"
36 |
37 | ICON_VPN="media/vpn.png"
38 | ICON_VPN_CONNECTED="media/vpn-connected.png"
39 |
40 | ICON_DNS="media/dns.png"
41 | ICON_DNS_USED="media/dns-used.png"
42 |
--------------------------------------------------------------------------------
/src/vpn.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . src/workflowHandler.sh
4 | . src/helpers.sh
5 |
6 | # Handle action
7 | if [ "$1" != "" ]; then
8 | IS_CONNECTED=$(test -z `scutil --nc status "$1" | head -n 1 | grep Connected` && echo 0 || echo 1);
9 | if [ $IS_CONNECTED -eq 1 ]; then
10 | scutil --nc stop "$1"
11 | else
12 | scutil --nc show "$1" | head -1 | grep PPP:L2TP 2>&1 > /dev/null
13 | if [ $? -eq 0 ]; then
14 | networksetup -connectpppoeservice "$1"
15 | else
16 | scutil --nc start "$1"
17 | fi
18 | fi
19 |
20 | exit
21 | fi
22 |
23 | while read -r LINE; do
24 | OUTPUT="$(getVPNInfo "$LINE")"
25 | IFS='~' read -r -a ARRAY <<< "$OUTPUT"
26 |
27 | addResult "" "${ARRAY[1]}" "${ARRAY[1]}" "${ARRAY[2]} (${ARRAY[0]})" "${ARRAY[3]}"
28 | done <<< "$(echo "$(scutil --nc list)" | awk 'NR>1')"
29 |
30 | getXMLResults
31 |
--------------------------------------------------------------------------------
/src/wifi.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . src/wifiCommon.sh
4 | . src/workflowHandler.sh
5 |
6 | # Handle action
7 | if [ "$1" != "" ]; then
8 | if [ "$1" == "On" ] || [ "$1" == "Off" ]; then
9 | networksetup -setairportpower "$INTERFACE" "$1"
10 | else
11 | echo "$1" | tr -d '\n'
12 | fi
13 | exit
14 | fi
15 |
16 | # Get interface mac address
17 | MAC=$(getWifiMac)
18 |
19 | # Handle Wi-Fi off state
20 | if [ "$(getWifiState "$INTERFACE")" == 0 ]; then
21 | addResult "" "On" "Turn $NAME on" "$INTERFACE ($MAC)" "$ICON_WIFI_ERROR"
22 | getXMLResults
23 | return
24 | fi
25 |
26 | # Get network configuration
27 | NETINFO=$(networksetup -getinfo "$NAME")
28 | NETCONFIG=$(getConnectionConfig "$NETINFO")
29 |
30 | # Output IPv4
31 | IPv4=$(getIPv4 "$NETINFO")
32 | if [ "$IPv4" != "" ]; then
33 | addResult "" "$IPv4" "$IPv4" "IPv4 address ($NETCONFIG)" "$ICON_WIFI"
34 | fi
35 |
36 | # Output IPv6
37 | IPv6=$(getIPv6 "$NETINFO")
38 | if [ "$IPv6" != "" ]; then
39 | addResult "" "$IPv6" "$IPv6" "IPv6 address ($NETCONFIG)" "$ICON_WIFI"
40 | fi
41 |
42 | # Output WiFi AP info
43 | INFO=$($AIRPORT --getinfo)
44 | SSID=$(getSSID "$INFO")
45 | BSSID=$(getBSSID "$INFO")
46 | AUTH=$(getAuth "$INFO")
47 |
48 | # Use BSSID with SSID as fallback
49 | SSID_NAME="$SSID ($BSSID)"
50 | if [ "$BSSID" == "" ]; then
51 | SSID_NAME="$SSID"
52 | fi
53 |
54 | if [ "$SSID" != "" ]; then
55 | addResult "" "$SSID" "$SSID_NAME" "$NAME access point ($AUTH)" "$ICON_WIFI"
56 | fi
57 |
58 | # Output global IP
59 | GLOBALIP=$(getGlobalIP)
60 | if [ "$GLOBALIP" != "" ]; then
61 | addResult "" "$GLOBALIP" "$GLOBALIP" "Global IP" "$ICON_WIFI"
62 | fi
63 |
64 | # Output VPN
65 | VPN=$(getVPN "$(scutil --nc list)")
66 | if [ "$VPN" != "" ]; then
67 | addResult "" "$VPN" "$VPN" "VPN connection" "$ICON_WIFI"
68 | fi
69 |
70 | # Output DNS list
71 | DNSSTRING=$(getDNS "$(networksetup -getdnsservers "$NAME")")
72 | if [ "$DNSSTRING" != "" ]; then
73 | addResult "" "$DNSSTRING" "$DNSSTRING" "DNS list" "$ICON_WIFI"
74 | fi
75 |
76 | addResult "" "Off" "Turn $NAME Off" "$INTERFACE ($MAC)" "$ICON_WIFI"
77 |
78 | getXMLResults
79 |
--------------------------------------------------------------------------------
/src/wifiCommon.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . src/helpers.sh
4 |
5 | LIST=$(networksetup -listallhardwareports)
6 | INTERFACE=$(getWifiInterface "$LIST")
7 | NAME=$(getWifiName "$LIST")
8 |
9 | AIRPORT="/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport"
10 |
--------------------------------------------------------------------------------
/src/workflowHandler.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | RESULTS=()
4 |
5 | ################################################################################
6 | # Adds a result to the result array
7 | #
8 | # $1 uid
9 | # $2 arg
10 | # $3 title
11 | # $4 subtitle
12 | # $5 icon
13 | # $6 valid
14 | # $7 autocomplete
15 | ###############################################################################
16 | addResult() {
17 | RESULT="- $(xmlEncode "$3")$(xmlEncode "$4")$(xmlEncode "$5")
"
18 | RESULTS+=("$RESULT")
19 | }
20 |
21 | ###############################################################################
22 | # Prints the feedback xml to stdout
23 | ###############################################################################
24 | getXMLResults() {
25 | echo ""
26 |
27 | # if [ "${#string[@]}" = "0" ]; then
28 | # echo "- No results foundPlease try another search term
"
29 | # fi
30 |
31 | for R in ${RESULTS[*]}; do
32 | echo "$R" | tr "\n" " "
33 | done
34 |
35 | echo ""
36 | }
37 |
38 | ###############################################################################
39 | # Escapes XML special characters with their entities
40 | ###############################################################################
41 | xmlEncode() {
42 | echo "$1" | sed -e 's/&/\&/g' -e 's/>/\>/g' -e 's/\</g' -e "s/'/\'/g" -e 's/"/\"/g'
43 | }
44 |
45 | ###############################################################################
46 | # Save key=value to the workflow properties
47 | #
48 | # $1 key
49 | # $2 value
50 | # $3 non-volatile 0/1
51 | # $4 filename (optional, filename will be "settings" if not specified)
52 | ###############################################################################
53 | setPref() {
54 | if [ "$3" = "0" ]; then
55 | local PREFDIR="$alfred_workflow_data"
56 | else
57 | local PREFDIR="$alfred_workflow_cache"
58 | fi
59 |
60 | if [ ! -d "$PREFDIR" ]; then
61 | mkdir -p "$PREFDIR"
62 | fi
63 |
64 | if [ -z "$4" ]; then
65 | local PREFFILE="${PREFDIR}/settings"
66 | else
67 | local PREFFILE="${PREFDIR}/$4"
68 | fi
69 |
70 | if [ ! -f "$PREFFILE" ]; then
71 | touch "$PREFFILE"
72 | fi
73 |
74 | local KEY_EXISTS=$(grep -c "$1=" "$PREFFILE")
75 | if [ "$KEY_EXISTS" = "1" ]; then
76 | local TMP=$(grep -ve "^$1" "$PREFFILE")
77 | echo "$TMP" > "$PREFFILE"
78 | fi
79 | echo "$1=$2" >> "$PREFFILE"
80 | }
81 |
82 | ###############################################################################
83 | # Read a value for a given key from the workflow preferences
84 | #
85 | # $1 key
86 | # $2 non-volatile 0/1
87 | # $3 filename (optional, filename will be "settings" if not specified)
88 | ###############################################################################
89 | getPref() {
90 | if [ "$2" = "0" ]; then
91 | local PREFDIR="$alfred_workflow_data"
92 | else
93 | local PREFDIR="$alfred_workflow_cache"
94 | fi
95 |
96 | if [ ! -d "$PREFDIR" ]; then
97 | return
98 | fi
99 |
100 | if [ -z "$3" ]; then
101 | local PREFFILE="${PREFDIR}/settings"
102 | else
103 | local PREFFILE="${PREFDIR}/$3"
104 | fi
105 |
106 | if [ ! -f "$PREFFILE" ]; then
107 | return
108 | fi
109 |
110 | local VALUE=$(sed "/^\#/d" "$PREFFILE" | grep "$1" | tail -n 1 | cut -d "=" -f2-)
111 | echo "$VALUE"
112 | }
113 |
114 | getLang() {
115 | defaults read .GlobalPreferences AppleLanguages | tr -d [:space:] | cut -c2-3
116 | }
117 |
--------------------------------------------------------------------------------
/tests/apTests.bats:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bats
2 |
3 | . src/helpers.sh
4 | load variables
5 |
6 | @test "getSavedAPs: get saved access points" {
7 | run getSavedAPs "$SAVED_APS"
8 | IFS='~' read -r -a ARRAY <<< "$output"
9 |
10 | [ "$status" -eq 0 ]
11 | [ "${ARRAY[0]}" == "Test-Network" ]
12 | [ "${ARRAY[1]}" == "Test-Network2" ]
13 | [ "${ARRAY[2]}" == "Martins iPhone" ]
14 | }
15 |
16 | @test "getAPDetails: get AP" {
17 | INPUT=" Test-Network 21:aa:4c:b4:cc:11 -24 6 Y US WPA2(PSK/AES/AES)"
18 |
19 | run getAPDetails "$INPUT"
20 | IFS='~' read -r -a ARRAY <<< "$output"
21 |
22 | [ "$status" -eq 0 ]
23 | [ "${ARRAY[0]}" == $PRIORITY_LOW ]
24 | [ "${ARRAY[1]}" == "Test-Network" ]
25 | [ "${ARRAY[2]}" == "21:aa:4c:b4:cc:11" ]
26 | [ "${ARRAY[3]}" == "-24" ]
27 | [ "${ARRAY[4]}" == "6" ]
28 | [ "${ARRAY[5]}" == "WPA2(PSK/AES/AES)" ]
29 | [ "${ARRAY[6]}" == $ICON_WIFI_LOCK ]
30 | }
31 |
32 | @test "getAPDetails: no BSSID on MacOS Monterey" {
33 | INPUT=" y6Uj4xYm -76 11 Y -- WPA2(PSK/AES/AES) "
34 |
35 | run getAPDetails "$INPUT"
36 | IFS='~' read -r -a ARRAY <<< "$output"
37 |
38 | [ "$status" -eq 0 ]
39 | [ "${ARRAY[0]}" == $PRIORITY_LOW ]
40 | [ "${ARRAY[1]}" == "y6Uj4xYm" ]
41 | [ "${ARRAY[2]}" == "" ]
42 | [ "${ARRAY[3]}" == "-76" ]
43 | [ "${ARRAY[4]}" == "11" ]
44 | [ "${ARRAY[5]}" == "WPA2(PSK/AES/AES)" ]
45 | [ "${ARRAY[6]}" == $ICON_WIFI_LOCK_2 ]
46 | }
47 |
48 | @test "getAPDetails: get multiband AP with spaces" {
49 | INPUT=" New AP 50:1d:bf:56:2f:2e -54 132,+1 Y DK WPA2(PSK/AES/AES) "
50 |
51 | run getAPDetails "$INPUT"
52 | IFS='~' read -r -a ARRAY <<< "$output"
53 |
54 | [ "${ARRAY[1]}" == "New AP" ]
55 | [ "${ARRAY[2]}" == "50:1d:bf:56:2f:2e" ]
56 | [ "${ARRAY[3]}" == "-54" ]
57 | [ "${ARRAY[4]}" == "132,+1" ]
58 | [ "${ARRAY[5]}" == "WPA2(PSK/AES/AES)" ]
59 | [ "${ARRAY[6]}" == $ICON_WIFI_LOCK ]
60 | }
61 |
62 | @test "getAPDetails: get random printer AP" {
63 | INPUT=" HP-Print-02-Officejet Pro 8600 9c:b6:54:58:05:02 -79 4 N -- WPA2(PSK/AES/AES) "
64 |
65 | run getAPDetails "$INPUT"
66 | IFS='~' read -r -a ARRAY <<< "$output"
67 |
68 | [ "${ARRAY[0]}" == $PRIORITY_LOW ]
69 | [ "${ARRAY[1]}" == "HP-Print-02-Officejet Pro 8600" ]
70 | [ "${ARRAY[2]}" == "9c:b6:54:58:05:02" ]
71 | [ "${ARRAY[3]}" == "-79" ]
72 | [ "${ARRAY[4]}" == "4" ]
73 | [ "${ARRAY[5]}" == "WPA2(PSK/AES/AES)" ]
74 | [ "${ARRAY[6]}" == $ICON_WIFI_LOCK_2 ]
75 | }
76 |
77 | @test "getAPDetails: get random printer AP on MacOS Monterey" {
78 | INPUT=" HP-Print-02-Officejet Pro 8600 -79 4 N -- WPA2(PSK/AES/AES) "
79 |
80 | run getAPDetails "$INPUT"
81 | IFS='~' read -r -a ARRAY <<< "$output"
82 |
83 | [ "${ARRAY[0]}" == $PRIORITY_LOW ]
84 | [ "${ARRAY[1]}" == "HP-Print-02-Officejet Pro 8600" ]
85 | [ "${ARRAY[2]}" == "" ]
86 | [ "${ARRAY[3]}" == "-79" ]
87 | [ "${ARRAY[4]}" == "4" ]
88 | [ "${ARRAY[5]}" == "WPA2(PSK/AES/AES)" ]
89 | [ "${ARRAY[6]}" == $ICON_WIFI_LOCK_2 ]
90 | }
91 |
92 | @test "getAPDetails: get unknown AP" {
93 | INPUT=" test 08:61:6e:c0:9b:ff -27 11 Y -- WPA(PSK/AES,TKIP/TKIP) WPA2(PSK/AES,TKIP/TKIP)"
94 |
95 | run getAPDetails "$INPUT"
96 | IFS='~' read -r -a ARRAY <<< "$output"
97 |
98 | [ "${ARRAY[0]}" == $PRIORITY_LOW ]
99 | [ "${ARRAY[1]}" == "test" ]
100 | [ "${ARRAY[2]}" == "08:61:6e:c0:9b:ff" ]
101 | [ "${ARRAY[5]}" == "WPA(PSK/AES,TKIP/TKIP) WPA2(PSK/AES,TKIP/TKIP)" ]
102 | [ "${ARRAY[6]}" == $ICON_WIFI_LOCK ]
103 | }
104 |
105 | @test "getAPDetails: active AP is marked with an icon" {
106 | INPUT=" New AP 50:1d:bf:56:2f:2e -54 132,+1 Y DK WPA2(PSK/AES/AES) "
107 |
108 | run getAPDetails "$INPUT" "50:1d:bf:56:2f:2e"
109 | IFS='~' read -r -a ARRAY <<< "$output"
110 |
111 | [ "${ARRAY[0]}" == $PRIORITY_HIGH ]
112 | [ "${ARRAY[1]}" == "New AP" ]
113 | [ "${ARRAY[2]}" == "50:1d:bf:56:2f:2e" ]
114 | [ "${ARRAY[6]}" == $ICON_WIFI_ACTIVE ]
115 | }
116 |
117 | @test "getAPDetails: active AP without BSSID is marked with an icon" {
118 | INPUT=" New AP -54 132,+1 Y DK WPA2(PSK/AES/AES) "
119 |
120 | run getAPDetails "$INPUT" "New AP"
121 | IFS='~' read -r -a ARRAY <<< "$output"
122 |
123 | [ "${ARRAY[0]}" == $PRIORITY_HIGH ]
124 | [ "${ARRAY[1]}" == "New AP" ]
125 | [ "${ARRAY[6]}" == $ICON_WIFI_ACTIVE ]
126 | }
127 |
128 | @test "getAPDetails: do not mark unknown active AP" {
129 | INPUT=" New AP 2 -54 132,+1 Y DK WPA2(PSK/AES/AES) "
130 |
131 | run getAPDetails "$INPUT" "New AP"
132 | IFS='~' read -r -a ARRAY <<< "$output"
133 |
134 | [ "${ARRAY[0]}" == $PRIORITY_LOW ]
135 | [ "${ARRAY[1]}" == "New AP 2" ]
136 | [ "${ARRAY[6]}" == $ICON_WIFI_LOCK ]
137 | }
138 |
139 | @test "getAPDetails: active BSSID can contain starting zeros" {
140 | INPUT=" New AP 50:0d:0f:56:00:2e -54 132,+1 Y DK WPA2(PSK/AES/AES) "
141 |
142 | run getAPDetails "$INPUT" "50:0d:0f:56:00:2e"
143 | IFS='~' read -r -a ARRAY <<< "$output"
144 |
145 | [ "${ARRAY[1]}" == "New AP" ]
146 | [ "${ARRAY[2]}" == "50:0d:0f:56:00:2e" ]
147 | [ "${ARRAY[6]}" == $ICON_WIFI_ACTIVE ]
148 | }
149 |
150 | @test "getAPDetails: filter empty SSIDs" {
151 | INPUT=" 50:0d:0f:56:00:2e -54 132,+1 Y DK WPA2(PSK/AES/AES) "
152 |
153 | run getAPDetails "$INPUT"
154 | IFS='~' read -r -a ARRAY <<< "$output"
155 |
156 | [ "${#ARRAY[@]}" == 0 ]
157 | }
158 |
159 | @test "getAPDetails: favorited AP is marked with an icon" {
160 | INPUT=" New AP 50:1d:bf:56:2f:2e -54 132,+1 Y DK WPA2(PSK/AES/AES) "
161 | AP_LIST="New AP
162 | Random other AP"
163 |
164 | run getAPDetails "$INPUT" "1234" "$AP_LIST"
165 | IFS='~' read -r -a ARRAY <<< "$output"
166 |
167 | [ "${ARRAY[0]}" == $PRIORITY_MEDIUM ]
168 | [ "${ARRAY[1]}" == "New AP" ]
169 | [ "${ARRAY[2]}" == "50:1d:bf:56:2f:2e" ]
170 | [ "${ARRAY[6]}" == $ICON_WIFI_STAR ]
171 | }
172 |
173 | @test "getAPDetails: open AP is marked with a plain icon" {
174 | INPUT=" New AP 50:1d:bf:56:2f:2e -54 132,+1 Y DK NONE "
175 |
176 | run getAPDetails "$INPUT"
177 | IFS='~' read -r -a ARRAY <<< "$output"
178 |
179 | [ "${ARRAY[1]}" == "New AP" ]
180 | [ "${ARRAY[6]}" == $ICON_WIFI ]
181 | }
182 |
183 | @test "getAPDetails: icon is set according to strength" {
184 | INPUT=" New AP 50:1d:bf:56:2f:2e -55 1 Y US NONE "
185 | run getAPDetails "$INPUT"
186 | IFS='~' read -r -a ARRAY <<< "$output"
187 | [ "${ARRAY[6]}" == "$ICON_WIFI_4" ]
188 |
189 | INPUT=" New AP 50:1d:bf:56:2f:2e -65 1 Y US NONE "
190 | run getAPDetails "$INPUT"
191 | IFS='~' read -r -a ARRAY <<< "$output"
192 | [ "${ARRAY[6]}" == "$ICON_WIFI_3" ]
193 |
194 | INPUT=" New AP 50:1d:bf:56:2f:2e -75 1 Y US NONE "
195 | run getAPDetails "$INPUT"
196 | IFS='~' read -r -a ARRAY <<< "$output"
197 | [ "${ARRAY[6]}" == $ICON_WIFI_2 ]
198 |
199 | INPUT=" New AP 50:1d:bf:56:2f:2e -85 1 Y US NONE "
200 | run getAPDetails "$INPUT"
201 | IFS='~' read -r -a ARRAY <<< "$output"
202 | [ "${ARRAY[6]}" == $ICON_WIFI_1 ]
203 | }
204 |
205 | @test "listContains: contains element" {
206 | run listContains "$AP_LIST" "bar baz"
207 | [ "$status" -eq 0 ]
208 | [ "$output" == 1 ]
209 | }
210 |
211 | @test "listContains: does not contain element" {
212 | run listContains "$AP_LIST" "not"
213 | [ "$output" == "" ]
214 | }
215 |
216 | @test "listContains: list is empty" {
217 | run listContains "" "foo"
218 | [ "$output" == "" ]
219 | }
220 |
221 | @test "listContains: element is empty" {
222 | run listContains "$AP_LIST"
223 | [ "$output" == "" ]
224 | }
225 |
--------------------------------------------------------------------------------
/tests/dnsTests.bats:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bats
2 |
3 | . src/helpers.sh
4 | load variables
5 |
6 | @test "getDNS: get current DNS list" {
7 | run getDNS "$DNS"
8 | [ "$output" = "8.8.8.8 / 8.8.4.4 / 192.168.1.1" ]
9 | }
10 |
11 | @test "parseDNSLine: parse a single dns config line" {
12 | run parseDNSLine "Google DNS:8.8.8.8,8.8.4.4"
13 | IFS='~' read -r -a ARRAY <<< "$output"
14 | [ "$status" -eq 0 ]
15 | [ "${ARRAY[0]}" == "Google DNS" ]
16 | [ "${ARRAY[1]}" == "8.8.8.8 / 8.8.4.4" ]
17 | [ "${ARRAY[2]}" == "$ICON_DNS" ]
18 | }
19 |
20 | @test "parseDNSLine: parse simple config" {
21 | run parseDNSLine "OpenerDNS:42.120.21.30"
22 | IFS='~' read -r -a ARRAY <<< "$output"
23 | [ "${ARRAY[0]}" == "OpenerDNS" ]
24 | [ "${ARRAY[1]}" == "42.120.21.30" ]
25 | }
26 |
27 | @test "parseDNSLine: parse with spaces" {
28 | run parseDNSLine " Random DNS : 1.2.3.4 , 6.7.8.9"
29 | IFS='~' read -r -a ARRAY <<< "$output"
30 | [ "${ARRAY[0]}" == "Random DNS" ]
31 | [ "${ARRAY[1]}" == "1.2.3.4 / 6.7.8.9" ]
32 | }
33 |
34 | @test "parseDNSLine: ignore comments" {
35 | run parseDNSLine "# comment"
36 | IFS='~' read -r -a ARRAY <<< "$output"
37 | [ "${ARRAY[0]}" == "" ]
38 | }
39 |
40 | @test "parseDNSLine: ignore comments with separator" {
41 | run parseDNSLine "# comment: this is a comment"
42 | IFS='~' read -r -a ARRAY <<< "$output"
43 | [ "${ARRAY[0]}" == "" ]
44 | }
45 |
46 | @test "parseDNSLine: ignore empty lines" {
47 | run parseDNSLine " "
48 | IFS='~' read -r -a ARRAY <<< "$output"
49 | [ "${ARRAY[0]}" == "" ]
50 | }
51 |
52 | @test "parseDNSLine: set used state" {
53 | run parseDNSLine "Google DNS:8.8.8.8,8.8.4.4" "8.8.8.8 / 8.8.4.4"
54 | IFS='~' read -r -a ARRAY <<< "$output"
55 | [ "${ARRAY[0]}" == "Google DNS (used)" ]
56 | [ "${ARRAY[1]}" == "8.8.8.8 / 8.8.4.4" ]
57 | [ "${ARRAY[2]}" == "$ICON_DNS_USED" ]
58 | }
59 |
60 | @test "parseDNSLine: handle invalid line" {
61 | run parseDNSLine "Invalid 1.2.3.4"
62 | IFS='~' read -r -a ARRAY <<< "$output"
63 | [ "${ARRAY[0]}" == "" ]
64 | }
65 |
66 | @test "parseDNSLine: handle missing ip" {
67 | run parseDNSLine "Invalid:"
68 | IFS='~' read -r -a ARRAY <<< "$output"
69 | [ "${ARRAY[0]}" == "" ]
70 | }
71 |
--------------------------------------------------------------------------------
/tests/ethernetTests.bats:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bats
2 |
3 | . src/helpers.sh
4 | load variables
5 |
6 | @test "getEthernetState: get ethernet state" {
7 | run getEthernetState en4
8 | [ "$status" -eq 0 ]
9 | [ "$output" = 1 -o "$output" = 0 ]
10 | }
11 |
12 | @test "getEthernetName: get name" {
13 | run getEthernetName "$LIST"
14 | [ "$status" -eq 0 ]
15 | [ "$output" = "Thunderbolt Ethernet" ]
16 | }
17 |
18 | @test "getEthernetName: get ax name" {
19 | run getEthernetName "$LIST3"
20 | [ "$status" -eq 0 ]
21 | [ "$output" = "AX88179A" ]
22 | }
23 |
24 | @test "getEthernetInterface: get interface Thunderbolt" {
25 | run getEthernetInterface "$LIST"
26 | [ "$status" -eq 0 ]
27 | [ "$output" = "en4" ]
28 | }
29 |
30 | @test "getEthernetInterface: get interface USB" {
31 | run getEthernetInterface "$LIST2"
32 | [ "$status" -eq 0 ]
33 | [ "$output" = "en7" ]
34 | }
35 |
36 | @test "getEthernetMac: get mac address" {
37 | run getEthernetMac "$LIST"
38 | [ "$status" -eq 0 ]
39 | [ "$output" = "40:0c:8d:00:ef:8c" ]
40 | }
41 |
--------------------------------------------------------------------------------
/tests/variables.bash:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | LIST="
4 | Hardware Port: Thunderbolt Ethernet
5 | Device: en4
6 | Ethernet Address: 40:0c:8d:00:ef:8c
7 |
8 | Hardware Port: Wi-Fi
9 | Device: en0
10 | Ethernet Address: f8:06:c1:00:a3:cc
11 |
12 | Hardware Port: Bluetooth PAN
13 | Device: en3
14 | Ethernet Address: b7:06:b1:01:a2:ce
15 |
16 | Hardware Port: Thunderbolt 1
17 | Device: en1
18 | Ethernet Address: f2:00:11:48:00:20
19 |
20 | Hardware Port: Thunderbolt 2
21 | Device: en2
22 | Ethernet Address: f2:00:12:48:50:22
23 |
24 | Hardware Port: Thunderbolt Bridge
25 | Device: bridge0
26 | Ethernet Address: cc:f6:b1:77:f7:02
27 |
28 | VLAN Configurations
29 | ==================="
30 |
31 | LIST2="
32 | Hardware Port: USB 10/100/1000 LAN
33 | Device: en7
34 | Ethernet Address: de:ad:be:ef:fe:ed
35 |
36 | Hardware Port: Wi-Fi
37 | Device: en0
38 | Ethernet Address: f8:06:c1:00:a3:cc
39 |
40 | VLAN Configurations
41 | ==================="
42 |
43 | LIST3="
44 | Hardware Port: Wi-Fi
45 | Device: en1
46 | Ethernet Address: f8:06:c1:00:a3:cc
47 |
48 | Hardware Port: AX88179A
49 | Device: en3
50 | Ethernet Address: de:ad:be:ef:fe:ed
51 |
52 | Hardware Port: Ethernet Adapter (en4)
53 | Device: en4
54 | Ethernet Address: de:ad:be:ef:fe:ee
55 |
56 | VLAN Configurations
57 | ==================="
58 |
59 | NETINFO='DHCP Configuration
60 | IP address: 192.168.1.100
61 | Subnet mask: 255.255.255.0
62 | Router: 192.168.1.1
63 | Client ID:
64 | IPv6: Automatic
65 | IPv6 IP address: none
66 | IPv6 Router: none
67 | Wi-Fi ID: f8:06:c1:00:a3:cc'
68 |
69 | INFO='agrCtlRSSI: -47
70 | agrExtRSSI: 0
71 | agrCtlNoise: -91
72 | agrExtNoise: 0
73 | state: running
74 | op mode: station
75 | lastTxRate: 450
76 | maxRate: 450
77 | lastAssocStatus: 0
78 | 802.11 auth: open
79 | link auth: wpa2-psk
80 | BSSID: c8:7:19:2c:0:6f
81 | SSID: Test-Network
82 | MCS: 23
83 | channel: 36,1'
84 |
85 | SCUTIL='Available network connection services in the current set (*=enabled):
86 | * (Disconnected) 9798DAED-21C7-44A1-B382-EFCE7E1373F1 PPP --> Modem (usbmodem1411) "Arduino Uno" [PPP:Modem]
87 | * (Disconnected) CBA1BCD8-D18D-4241-9EF4-5656AF89F09B PPP --> Modem (usbserial) "USB-Serial Controller D" [PPP:Modem]
88 | * (Disconnected) F9BABC6E-649F-4113-95BC-94E1467FCBE8 PPP --> Modem (usbmodem1d112) "SAMSUNG_Android" [PPP:Modem]
89 | * (Connected) 65F5A798-4B98-4DA1-87D8-9D605FFF6188 PPP --> L2TP "Test-VPN" [PPP:L2TP]'
90 |
91 | DNS="8.8.8.8
92 | 8.8.4.4
93 | 192.168.1.1"
94 |
95 | SAVED_APS=" Test-Network
96 | Test-Network2
97 | Martins iPhone"
98 |
99 | AP_LIST="foo
100 | bar baz
101 | qux"
102 |
--------------------------------------------------------------------------------
/tests/vpnTests.bats:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bats
2 |
3 | . src/helpers.sh
4 | load variables
5 |
6 | @test "getVPNInfo: get vpn info" {
7 | INPUT="* (Disconnected) 65F5A799-4C98-4DA1-87D7-9D605D9D666C IPSec \"My-VPN\" [IPSec]"
8 |
9 | run getVPNInfo "$INPUT"
10 | IFS='~' read -r -a ARRAY <<< "$output"
11 |
12 | [ "$status" -eq 0 ]
13 | [ "${ARRAY[0]}" == "Disconnected" ]
14 | [ "${ARRAY[1]}" == "My-VPN" ]
15 | [ "${ARRAY[2]}" == "IPSec" ]
16 | [ "${ARRAY[3]}" == "$ICON_VPN" ]
17 | }
18 |
19 | @test "getVPNInfo: get connected vpn info" {
20 | INPUT="* (Connected) 65F5A799-4C98-4DA1-87D7-9D605D9D666C IPSec \"Another: VPN\" [IPSec]"
21 |
22 | run getVPNInfo "$INPUT"
23 | IFS='~' read -r -a ARRAY <<< "$output"
24 |
25 | [ "$status" -eq 0 ]
26 | [ "${ARRAY[0]}" == "Connected" ]
27 | [ "${ARRAY[1]}" == "Another: VPN" ]
28 | [ "${ARRAY[2]}" == "IPSec" ]
29 | [ "${ARRAY[3]}" == "$ICON_VPN_CONNECTED" ]
30 | }
31 |
32 | @test "getVPNInfo: get other service" {
33 | INPUT="* (Disconnected) 04D2AFD3-F0BC-47BB-9C91-9E9B4F5675A6 PPP --> L2TP \"Some L2TP VPN\" [PPP:L2TP]"
34 |
35 | run getVPNInfo "$INPUT"
36 | IFS='~' read -r -a ARRAY <<< "$output"
37 |
38 | [ "$status" -eq 0 ]
39 | [ "${ARRAY[0]}" == "Disconnected" ]
40 | [ "${ARRAY[1]}" == "Some L2TP VPN" ]
41 | [ "${ARRAY[2]}" == "PPP:L2TP" ]
42 | [ "${ARRAY[3]}" == "$ICON_VPN" ]
43 | }
44 |
45 | @test "getVPNInfo: get connected vpn info with paranthesis" {
46 | INPUT="* (Connected) 65F5A799-4C98-4DA1-87D7-9D605D9D666C IPSec (com.vpn.vpn) \"Another: VPN\" [IPSec]"
47 |
48 | run getVPNInfo "$INPUT"
49 | IFS='~' read -r -a ARRAY <<< "$output"
50 |
51 | [ "$status" -eq 0 ]
52 | [ "${ARRAY[0]}" == "Connected" ]
53 | [ "${ARRAY[1]}" == "Another: VPN" ]
54 | [ "${ARRAY[2]}" == "IPSec" ]
55 | [ "${ARRAY[3]}" == "$ICON_VPN_CONNECTED" ]
56 | }
--------------------------------------------------------------------------------
/tests/wifiTests.bats:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bats
2 |
3 | . src/helpers.sh
4 | load variables
5 |
6 | @test "getWifiState: get wifi state" {
7 | run getWifiState en0
8 | [ "$status" -eq 0 ]
9 | [ "$output" = 1 -o "$output" = 0 ]
10 | }
11 |
12 | @test "getWifiName: get name" {
13 | run getWifiName "$LIST"
14 | [ "$status" -eq 0 ]
15 | [ "$output" = "Wi-Fi" ]
16 | }
17 |
18 | @test "getWifiInterface: get interface" {
19 | run getWifiInterface "$LIST"
20 | [ "$status" -eq 0 ]
21 | [ "$output" = "en0" ]
22 | }
23 |
24 | @test "getWifiMac: get mac address" {
25 | run getWifiMac "$LIST"
26 | [ "$status" -eq 0 ]
27 | [ "$output" = "f8:06:c1:00:a3:cc" ]
28 | }
29 |
30 | @test "getConnectionConfig: get connection config" {
31 | run getConnectionConfig "$NETINFO"
32 | [ "$output" = "DHCP Configuration" ]
33 | }
34 |
35 | @test "getIPv4: get IPv4" {
36 | run getIPv4 "$NETINFO"
37 | [ "$output" = "192.168.1.100" ]
38 | }
39 |
40 | @test "getIPv6: get non-existing IPv6" {
41 | run getIPv6 "$NETINFO"
42 | [ "$output" = "" ]
43 | }
44 |
45 | @test "getSSID: get SSID" {
46 | run getSSID "$INFO"
47 | [ "$output" = "Test-Network" ]
48 | }
49 |
50 | @test "getBSSID: get BSSID" {
51 | run getBSSID "$INFO"
52 | [ "$output" = "c8:07:19:2c:00:6f" ]
53 | }
54 |
55 | @test "getBSSID: no BSSID" {
56 | run getBSSID " BSSID:"
57 | [ "$output" = "" ]
58 | }
59 |
60 | @test "getBSSID: zero pads BSSID" {
61 | run getBSSID " BSSID: c8:7:19:2c:0:6f"
62 | [ "$output" = "c8:07:19:2c:00:6f" ]
63 | }
64 |
65 | @test "getAuth: get auth" {
66 | run getAuth "$INFO"
67 | [ "$output" = "auth: wpa2-psk" ]
68 | }
69 |
70 | @test "getGlobalIP: get global IP" {
71 | run getGlobalIP
72 | [[ "$output" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]
73 | }
74 |
75 | @test "getGlobalIP: handle invalid resolver" {
76 | run getGlobalIP "non-existing"
77 | [[ "$output" = "" ]]
78 | }
79 |
80 | @test "getVPN: get connected VPN" {
81 | run getVPN "$SCUTIL"
82 | [ "$output" = "Test-VPN" ]
83 | }
84 |
--------------------------------------------------------------------------------