Skip to content

Commit

Permalink
Add a new example mikey.html, update github pages ci.
Browse files Browse the repository at this point in the history
  • Loading branch information
taichunmin committed Mar 4, 2023
1 parent f5bbbc0 commit 17b2ac8
Show file tree
Hide file tree
Showing 11 changed files with 287 additions and 150 deletions.
37 changes: 27 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,24 @@ on:
pull_request:
branches: [ master ]

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: true

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Checkout
uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
node-version: 18
cache: 'yarn'
- name: install, lint, test, build
run: |
Expand All @@ -29,23 +39,30 @@ jobs:
deploy:
if: github.ref == 'refs/heads/master'
needs: test
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Checkout
uses: actions/checkout@v3
- name: Setup Pages
uses: actions/configure-pages@v3
- uses: actions/setup-node@v3
with:
node-version: 16
node-version: 18
cache: 'yarn'
- name: install, build
- name: install and build
run: |
yarn
yarn build
- name: 把網頁放到 GitHub Pages 的專屬分支上
uses: peaceiris/actions-gh-pages@v3
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
force_orphan: true
path: './dist'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1
- name: 發布至 npm
uses: JS-DevTools/npm-publish@v1
with:
Expand Down
6 changes: 4 additions & 2 deletions build.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url))
const log = createLogger('app:index')

export const build = async () => {
const sitemapUrls = []

const PUG_OPTIONS = {
basedir: path.resolve(__dirname),
baseurl: getBaseurl(),
NODE_ENV: getenv('NODE_ENV', 'production'),
}

const sitemapUrls = [
new URL('./docs/', PUG_OPTIONS.baseurl).href,
]

const htmlMinifierOptions = {
caseSensitive: true,
collapseBooleanAttributes: true,
Expand Down
5 changes: 5 additions & 0 deletions documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ toc:
URL: <http://taichunmin.idv.tw/pn532.js/m1-uid-scanner.html>
This tools can scan UID of NFC Type A Tags via Web Bluetooth or Web Serial.
- name: mfkey32v2 and mfkey64
description: |
URL: <http://taichunmin.idv.tw/pn532.js/mfkey.html>
An online tool for mfkey32v2 and mfkey64 that recover mifare key from encrypted data obtained from reader-only attack or sniff communications between reader and card.
- name: Key Detector for 北方智能卡
description: |
URL: <http://taichunmin.idv.tw/pn532.js/detector-shop143630998.html>
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"dayjs": "^1.11.7",
"documentation": "^14.0.1",
"dotenv": "^16.0.3",
"eslint": "^8.32.0",
"eslint": "^8.33.0",
"eslint-config-standard": "^17.0.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-n": "^15.6.1",
Expand All @@ -48,7 +48,7 @@
"livereload": "^0.9.3",
"node-watch": "^0.7.3",
"pug": "^3.0.2",
"rollup": "^3.11.0",
"rollup": "^3.14.0",
"rollup-plugin-version-injector": "^1.3.3",
"serve-static": "^1.15.0",
"web-streams-polyfill": "^3.2.1"
Expand Down
2 changes: 1 addition & 1 deletion web/detector-furui.pug
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ block content
option(value="1") S70CL1 (4k, 4 bytes UID)
.input-group.input-group-sm.mb-2.was-validated
.input-group-prepend: span.input-group-text.justify-content-center UID
input.form-control(pattern="[\\dA-Fa-f]{8}", placeholder="請輸入 8 位數 16 進位的 UID", required, type="text", v-model="h.uid")
input.form-control(pattern="[\\dA-Fa-f]{8}", placeholder="請輸入 8 位數 16 進位的 UID", required, v-model="h.uid")
.input-group-append: button.btn.btn-outline-danger(type="button", @click="h.uid = ''") 清空
.row.mx-n1
.col.px-1: button.btn.btn-block.btn-success(@click="btnReadDetector") #[i.fa.fa-fw.fa-sign-out] 讀取卡號
Expand Down
2 changes: 1 addition & 1 deletion web/detector-shop143630998.pug
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ block content
option(value="1") S70CL1 (4k, 4 bytes UID)
.input-group.input-group-sm.mb-2.was-validated
.input-group-prepend: span.input-group-text.justify-content-center UID
input.form-control(pattern="[\\dA-Fa-f]{8}", placeholder="請輸入 8 位數 16 進位的 UID", required, type="text", v-model="h.uid")
input.form-control(pattern="[\\dA-Fa-f]{8}", placeholder="請輸入 8 位數 16 進位的 UID", required, v-model="h.uid")
.input-group-append: button.btn.btn-outline-danger(type="button", @click="h.uid = ''") 清空
.row.mx-n1
.col.px-1: button.btn.btn-block.btn-success(@click="btnReadDetector") #[i.fa.fa-fw.fa-sign-out] 讀取卡號
Expand Down
2 changes: 1 addition & 1 deletion web/index.pug
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
doctype html
-
const redirect = 'https://taichunmin.idv.tw/pn532.js/docs/'
const redirect = `${baseurl}docs/`
html(lang="en-US")
head
meta(charset="UTF-8")
Expand Down
8 changes: 4 additions & 4 deletions web/m1-eml-toolkit.pug
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ block content
.col.px-1: button.btn.btn-block.btn-danger(type="button", @click="btnWriteGen2") 寫入資料
.form-group
label.mb-1 Common
button.btn.mt-1.btn-block.btn-primary(@click="btnEditEml") 編輯卡片資料
button.btn.mt-1.btn-block.btn-info(@click="btnEditMfkeys") 編輯卡片金鑰
button.btn.mt-1.btn-block.btn-outline-dark(@click="btnLoadKeysFromEml") 從卡片資料提取金鑰
button.btn.mt-1.btn-block.btn-outline-warning(@click="btnSetBlankEml") 重設為空白卡片資料
button.btn.mt-1.btn-block.btn-primary(type="button", @click="btnEditEml") 編輯卡片資料
button.btn.mt-1.btn-block.btn-info(type="button", @click="btnEditMfkeys") 編輯卡片金鑰
button.btn.mt-1.btn-block.btn-outline-dark(type="button", @click="btnLoadKeysFromEml") 從卡片資料提取金鑰
button.btn.mt-1.btn-block.btn-outline-warning(type="button", @click="btnSetBlankEml") 重設為空白卡片資料
.modal.fade(data-backdrop="static", data-keyboard="false", tabindex="-1", ref="exportimport")
.modal-dialog.modal-dialog-centered.modal-xl.align-items-stretch
.modal-content
Expand Down
15 changes: 7 additions & 8 deletions web/m1-uid4b-writer.pug
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,13 @@ block content
.modal.fade(data-keyboard="false", tabindex="-1", ref="cardPicker")
.modal-dialog.modal-dialog-centered.modal-xl
.modal-content
.modal-header
.modal-title.w-100.d-flex.align-items-center
.flex-fill
.input-group
.input-group-prepend: span.input-group-text 模糊搜尋
input.form-control#h-keyword(placeholder="模糊搜尋: 名稱、UID" v-model="cardPicker.keyword")
.input-group-append: button.btn.btn-outline-danger(type="button", @click="cardPicker.keyword = ''") 清空
button.close(type="button", data-dismiss="modal"): span &times;
.modal-header.d-flex.align-items-center
.modal-title.flex-fill
.input-group
.input-group-prepend: span.input-group-text 模糊搜尋
input.form-control#h-keyword(placeholder="模糊搜尋: 名稱、UID" v-model="cardPicker.keyword")
.input-group-append: button.btn.btn-outline-danger(type="button", @click="cardPicker.keyword = ''") 清空
button.close(type="button", data-dismiss="modal"): span &times;
.modal-body.p-0
ul.list-group.list-group-flush
button.list-group-item.list-group-item-action.d-flex.flex-column(
Expand Down
110 changes: 110 additions & 0 deletions web/mfkey.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
extends /layout/default

block beforehtml
- const title = 'mfkey'

block style
meta(property="og:description", content=title)
meta(property="og:locale", content="zh_TW")
meta(property="og:title", content=title)
meta(property="og:type", content="website")
meta(property="og:url", content=`${baseurl}mf-key-detector.html`)
style
:sass
[v-cloak]
display: none
body, .h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6
font-family: 'Noto Sans TC', sans-serif
.letter-spacing-n1px
letter-spacing: -1px
.input-group-prepend > .input-group-text
width: 60px
block content
#app.my-3.container.text-monospace(v-cloak)
h3.mb-3.text-center= title
.row
.col.col-md-6: .card.mb-3
.card-header #[i.fa.fa-fw.fa-star-o] mfkey32v2
.card-body
.input-group.input-group-sm.mb-2.was-validated(v-for="k of ['uid', 'nt0', 'nr0', 'ar0', 'nt1', 'nr1', 'ar1']")
.input-group-prepend: span.input-group-text.justify-content-center {{ k }}
input.form-control(pattern="[\\dA-Fa-f]{8}", :placeholder="`請輸入 8 位數 16 進位的 ${k}`", required, v-model="mfkey32v2[k]", maxlength="8")
.input-group-append: button.btn.btn-outline-danger(type="button", @click="mfkey32v2[k] = ''") 清空
.input-group.input-group-sm.mb-2.was-validated
.input-group-prepend: span.input-group-text.justify-content-center key
input.form-control(readonly, :value="mfkey32v2.key")
.input-group-append: button.btn.btn-outline-success(type="button", @click="btnCopy(mfkey32v2.key)") 複製
button.btn.mt-3.btn-block.btn-success(@click="btnMfkey32v2") #[i.fa.fa-fw.fa-key] 破解金鑰
.col.col-md-6: .card.mb-3
.card-header #[i.fa.fa-fw.fa-star-o] mfkey64
.card-body
.input-group.input-group-sm.mb-2.was-validated(v-for="k of ['uid', 'nt', 'nr', 'ar', 'at']")
.input-group-prepend: span.input-group-text.justify-content-center {{ k }}
input.form-control(pattern="[\\dA-Fa-f]{8}", :placeholder="`請輸入 8 位數 16 進位的 ${k}`", required, v-model="mfkey64[k]", maxlength="8")
.input-group-append: button.btn.btn-outline-danger(type="button", @click="mfkey64[k] = ''") 清空
.input-group.input-group-sm.mb-2.was-validated
.input-group-prepend: span.input-group-text.justify-content-center key
input.form-control(readonly, :value="mfkey64.key")
.input-group-append: button.btn.btn-outline-success(type="button", @click="btnCopy(mfkey64.key)") 複製
button.btn.mt-3.btn-block.btn-success(@click="btnMfkey64") #[i.fa.fa-fw.fa-key] 破解金鑰

block script
script.
const { Crypto1, Pn532: { utils: Pn532utils } } = window

window.vm = new Vue({
el: '#app',
data: {
mfkey32v2: { uid: '', nt0: '', nr0: '', ar0: '', nt1: '', nr1: '', ar1: '', key: '' },
mfkey64: { uid: '', nt: '', nr: '', ar: '', at: '', key: '' },
},
methods: {
async btnMfkey32v2 () {
try {
for (let k of ['uid', 'nt0', 'nr0', 'ar0', 'nt1', 'nr1', 'ar1']) {
if (!/^[0-9a-fA-F]{8}$/.test(this.mfkey32v2[k])) throw new Error(`欄位 ${k} 格式錯誤`)
}
this.showLoading('正在破解...', '正在計算金鑰')
await Pn532utils.sleep(100)
this.mfkey32v2.key = Crypto1.mfkey32v2({ ...this.mfkey32v2 }).hex
await Swal.fire({ icon: 'success', title: '破解成功', text: `金鑰為 ${this.mfkey32v2.key}` })
} catch (err) {
await Swal.fire({ icon: 'error', title: '破解失敗', text: err.message })
}
},
async btnMfkey64 () {
try {
for (let k of ['uid', 'nt', 'nr', 'ar', 'at']) {
if (!/^[0-9a-fA-F]{8}$/.test(this.mfkey64[k])) throw new Error(`欄位 ${k} 格式錯誤`)
}
this.showLoading('正在破解...', '正在計算金鑰')
await Pn532utils.sleep(100)
this.mfkey64.key = Crypto1.mfkey64({ ...this.mfkey64 }).hex
await Swal.fire({ icon: 'success', title: '破解成功', text: `金鑰為 ${this.mfkey64.key}` })
} catch (err) {
await Swal.fire({ icon: 'error', title: '破解失敗', text: err.message })
}
},
async btnCopy (text, container = null) {
if (!container) container = document.body
const dom = document.createElement('textarea')
dom.value = text
container.appendChild(dom)
dom.select()
dom.setSelectionRange(0, 1e6) // For mobile devices
document.execCommand('copy')
container.removeChild(dom)
await Swal.fire({ icon: 'success', title: '複製成功' })
},
showLoading (title, text) {
Swal.fire({
title,
text,
allowOutsideClick: false,
showConfirmButton: false,
willOpen: () => { Swal.showLoading() },
})
},
},
})
Loading

0 comments on commit 17b2ac8

Please sign in to comment.