1-
21type SASinput = {
32 accountKey : string
43 accountName : string
@@ -23,11 +22,12 @@ const truncatedISO8061Date = (date: Date) => {
2322 return dateString . substring ( 0 , dateString . length - 5 ) + 'Z'
2423}
2524
26- const computeHMACSHA256 = async ( stringToSign : string , accountKey : string ) => {
25+ const computeHMACSHA256 = async ( stringToSign : string , accountKey : string ) : Promise < string > => {
2726 const enc = new TextEncoder ( )
2827 const signatureUTF8 = enc . encode ( stringToSign )
2928 const key = await crypto . subtle . importKey (
3029 'raw' ,
30+ //@ts -ignore
3131 Buffer . from ( accountKey , 'base64' ) ,
3232 {
3333 name : 'HMAC' ,
@@ -41,6 +41,7 @@ const computeHMACSHA256 = async (stringToSign: string, accountKey: string) => {
4141
4242 const digest = await crypto . subtle . sign ( 'HMAC' , key , signatureUTF8 )
4343
44+ //@ts -ignore
4445 return Buffer . from ( digest ) . toString ( 'base64' )
4546}
4647
@@ -57,39 +58,51 @@ const getSASqueryParams = async (input: SASinput) => {
5758 const version = '2018-11-09'
5859 const signedSnapshotTime = undefined
5960
60- const stringToSign = [
61- input . permissions ? input . permissions : '' ,
62- input . startsOn ? truncatedISO8061Date ( input . startsOn ) : '' ,
63- truncatedISO8061Date ( input . expiresOn ) ,
64- getCanonicalName ( input . accountName , input . containerName , input . blobName ) ,
65- input . identifier ? input . identifier : '' ,
66- input . ipRange ? input . ipRange : '' ,
67- input . protocol ? input . protocol : '' ,
68- version ,
69- resource ,
70- signedSnapshotTime ,
71- input . cacheControl ? input . cacheControl : '' ,
72- input . contentDisposition ? input . contentDisposition : '' ,
73- input . contentEncoding ? input . contentEncoding : '' ,
74- input . contentLanguage ? input . contentLanguage : '' ,
75- input . contentType ? input . contentType : '' ,
76- ] . join ( '\n' )
61+ let queryParams = {
62+ sp : input . permissions ?? '' ,
63+ st : input . startsOn ? truncatedISO8061Date ( input . startsOn ) : '' ,
64+ se : truncatedISO8061Date ( input . expiresOn ) ,
65+ name : getCanonicalName ( input . accountName , input . containerName , input . blobName ) ,
66+ si : input . identifier ?? '' ,
67+ sip : input . ipRange ?? '' ,
68+ spr : input . protocol ?? '' ,
69+ sv : version ,
70+ sr : resource ,
71+ ne : signedSnapshotTime ,
72+ rscc : input . cacheControl ?? '' ,
73+ rscd : input . contentDisposition ?? '' ,
74+ rsce : input . contentEncoding ?? '' ,
75+ rscl : input . contentLanguage ?? '' ,
76+ rsct : input . contentType ?? '' ,
77+ }
78+
79+ const stringToSign = Object . values ( queryParams ) . join ( '\n' )
7780
7881 const signature = await computeHMACSHA256 ( stringToSign , input . accountKey )
82+ const { name, ne, ...rest } = queryParams
7983
80- return `sv=${ version } &spr=https&se=${ encodeURIComponent (
81- truncatedISO8061Date ( input . expiresOn )
82- ) } &sr=b&sp=rw&sig=${ encodeURIComponent ( signature ) } `
84+ //@ts -ignore
85+ queryParams . sig = signature
86+
87+ return Object . keys ( { ...rest , ...{ sig : signature } } )
88+ . map ( ( key ) => {
89+ if ( queryParams [ key ] === '' ) return
90+
91+ return `${ key } =${ encodeURIComponent ( queryParams [ key ] ) } `
92+ } )
93+ . join ( '&' )
8394}
8495
85- export default async ( input : SASinput ) => {
86- const url = [ input . containerName , input . blobName ] . filter ( el => el ) . join ( '/' )
96+ const createBlobSas = async ( input : SASinput ) => {
97+ const url = [ input . containerName , input . blobName ] . filter ( ( el ) => el ) . join ( '/' )
8798 const storageUri = new URL ( url , `https://${ input . accountName } .blob.core.windows.net` )
8899 const queryParams = await getSASqueryParams ( input )
89100
90101 storageUri . search = queryParams
91102
92103 return {
93- blobSasUrl : url . toString ( ) ,
104+ blobSasUrl : storageUri . toString ( ) ,
94105 }
95106}
107+
108+ export { createBlobSas }
0 commit comments