sms close #28
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,6 +2,7 @@
|
||||
/ui
|
||||
/log
|
||||
/jwk.json
|
||||
/tc.json
|
||||
/dbimport
|
||||
/dbexport
|
||||
/json
|
||||
|
@ -9,7 +9,7 @@ cd ismism.ts
|
||||
|
||||
deno bundle src/serve.ts ../cli/serve.js
|
||||
deno bundle cli/dbinit.ts ../cli/dbinit.js
|
||||
deno bundle cli/keygen.ts ../cli/keygen.js
|
||||
deno bundle cli/smstst.ts ../cli/smstst.js
|
||||
|
||||
cp ui/index.html ../ui/index.html
|
||||
deno bundle ui/bind.ts ../ui/bind.js
|
||||
|
@ -1,3 +0,0 @@
|
||||
import { keygen } from "../src/aut.ts"
|
||||
|
||||
await keygen(true)
|
10
ismism.ts/cli/smstst.ts
Normal file
10
ismism.ts/cli/smstst.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { smssend } from "../src/sms.ts"
|
||||
|
||||
console.log("sending test sms")
|
||||
|
||||
const resok = await smssend("18200145532", Math.round(Math.random() * 1000000), 78)
|
||||
console.log(JSON.stringify(resok))
|
||||
|
||||
const reserr = await smssend("1820014553-", Math.round(Math.random() * 1000000), 78)
|
||||
console.log(JSON.stringify(reserr))
|
||||
|
@ -1,4 +1,5 @@
|
||||
import * as base64 from "https://deno.land/std@0.162.0/encoding/base64url.ts"
|
||||
import * as hex from "https://deno.land/std@0.162.0/encoding/hex.ts"
|
||||
|
||||
const te = new TextEncoder()
|
||||
const td = new TextDecoder()
|
||||
@ -24,3 +25,14 @@ export function from_base64(
|
||||
): Uint8Array {
|
||||
return base64.decode(s)
|
||||
}
|
||||
|
||||
export function to_hex(
|
||||
b: ArrayBuffer
|
||||
): string {
|
||||
return from_u8(hex.encode(new Uint8Array(b)))
|
||||
}
|
||||
export function from_hex(
|
||||
s: string
|
||||
): Uint8Array {
|
||||
return hex.decode(to_u8(s))
|
||||
}
|
||||
|
@ -6,16 +6,17 @@ const alg = {
|
||||
}
|
||||
|
||||
export function key(
|
||||
k: string
|
||||
k: string | ArrayBuffer
|
||||
): Promise<CryptoKey> {
|
||||
return crypto.subtle.importKey("raw", to_u8(k), alg, false, ["sign", "verify"])
|
||||
if (typeof k === "string") k = to_u8(k)
|
||||
return crypto.subtle.importKey("raw", k, alg, false, ["sign", "verify"])
|
||||
}
|
||||
|
||||
export function sign(
|
||||
key: CryptoKey,
|
||||
str: string,
|
||||
data: string,
|
||||
) {
|
||||
return crypto.subtle.sign(alg.name, key, to_u8(str))
|
||||
return crypto.subtle.sign(alg.name, key, to_u8(data))
|
||||
}
|
||||
|
||||
export function verify(
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { serve } from "https://deno.land/std@0.163.0/http/server.ts"
|
||||
import { utc_short } from "./date.ts"
|
||||
import { utc_short } from "./ontic/utc.ts"
|
||||
import { query } from "./query.ts"
|
||||
|
||||
let etag = `W/"${Date.now()}"`
|
||||
|
75
ismism.ts/src/sms.ts
Normal file
75
ismism.ts/src/sms.ts
Normal file
@ -0,0 +1,75 @@
|
||||
import { to_hex } from "./ontic/base.ts"
|
||||
import { digest, key, sign } from "./ontic/crypt.ts"
|
||||
import { utc_date } from "./ontic/utc.ts"
|
||||
|
||||
const tc: {
|
||||
id: string,
|
||||
key: string,
|
||||
service: string,
|
||||
endpoint: string,
|
||||
region: string,
|
||||
ver: string,
|
||||
appid: string,
|
||||
sign: string,
|
||||
template: string,
|
||||
} = JSON.parse(await Deno.readTextFile("./tc.json"))
|
||||
|
||||
type SendResponse = {
|
||||
Response: { SendStatusSet: { Code: string }[] }
|
||||
}
|
||||
|
||||
export async function smssend(
|
||||
nbr: string,
|
||||
code: number,
|
||||
hr: number
|
||||
) {
|
||||
const body = JSON.stringify({
|
||||
PhoneNumberSet: [nbr],
|
||||
SmsSdkAppId: tc.appid,
|
||||
SignName: tc.sign,
|
||||
TemplateId: tc.template,
|
||||
TemplateParamSet: [`${code}`, `${hr}`],
|
||||
})
|
||||
const alg = "TC3-HMAC-SHA256"
|
||||
const t = Math.round(Date.now() / 1000)
|
||||
const d = utc_date(t * 1000)
|
||||
const scope = `${d}/${tc.service}/tc3_request`
|
||||
const sigheader = "content-type;host"
|
||||
const content_type = "application/json; charset=utf-8"
|
||||
const req = `POST
|
||||
/
|
||||
|
||||
content-type:${content_type}
|
||||
host:${tc.endpoint}
|
||||
|
||||
${sigheader}
|
||||
${to_hex(await digest(body))}`
|
||||
|
||||
const str = `${alg}
|
||||
${t}
|
||||
${scope}
|
||||
${to_hex(await digest(req))}`
|
||||
const kdate = await sign(await key(`TC3${tc.key}`), d)
|
||||
const kservice = await sign(await key(kdate), tc.service)
|
||||
const ksign = await sign(await key(kservice), "tc3_request")
|
||||
const signature = to_hex(await sign(await key(ksign), str))
|
||||
const authorization = `${alg} Credential=${tc.id}/${scope}, SignedHeaders=${sigheader}, Signature=${signature}`
|
||||
|
||||
const res = await fetch(`https://${tc.endpoint}`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Authorization": authorization,
|
||||
"Content-Type": content_type,
|
||||
"Host": tc.endpoint,
|
||||
"X-TC-Action": "SendSms",
|
||||
"X-TC-Timestamp": `${t}`,
|
||||
"X-TC-Version": tc.ver,
|
||||
"X-TC-Region": tc.region,
|
||||
},
|
||||
body,
|
||||
})
|
||||
const json = await res.json() as SendResponse
|
||||
return {
|
||||
json, sent: json.Response.SendStatusSet[0]?.Code === "Ok"
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// deno-lint-ignore-file no-window-prefix
|
||||
import { utc_medium, utc_short } from "../src/date.ts"
|
||||
import { utc_medium, utc_short } from "../src/ontic/utc.ts"
|
||||
import type { Agenda, Soc, User } from "../src/query.ts"
|
||||
import type { Goal, Tag, Rec, Work, Worker, Fund } from "../src/typ.ts"
|
||||
import type { NRec, RecOf } from "../src/db.ts"
|
||||
|
Reference in New Issue
Block a user